Queries¶
Fazer pesquisas é essencial para utilizar um ODM e poder fazer pesquisas complexas é ainda melhor quando assim o é permitido.
O MongoDB é conhecido pela sua performance ao pesquisas uma base de dados e é muito rápido nisso.
Ao fazer pesquisas num documento, o ODM permite duas maneiras diferentes de pesquisa. Uma é utilizando o manager interno e a segunda é utilizando o queryset.
Na realidade, o manager
e o queryset
são muito parecidos, mas para fins internos, foi decidido chamá-los desta maneira para deixar claro como as pesquisas podem ser feitas.
Se ainda não viu a seção de documentos, agora seria uma ótima altura para dar uma vista de olhos e se familiarizar.
Para fins desta documentação, mostraremos como fazer pesquisas utilizando tanto o manager
quanto o queryset
.
Tanto o queryset quanto o manager funcionam muito bem quando combinados. No final, cabe ao programador decidir qual prefere.
Manager and QuerySet¶
Quando se faz pesquisas dentro do Mongoz, isto retorna um objeto se deseja apenas um resultado ou um queryset
/manager
que é a representação interna de varios resultados.
Se está familiarizado com as querysets do Django, isto é quase a mesma coisa e por quase é porque o mongoz restringe as atribuições de variáveis da queryset de forma mais livre.
Vamos nos familiarizar com as pesquisas.
Vamos supor que tenha o seguinte documento User
definido.
import mongoz
database_uri = "mongodb://localhost:27017"
registry = mongoz.Registry(database_uri)
class User(mongoz.Document):
is_active: bool = mongoz.Boolean(default=True)
first_name: str = mongoz.String(max_length=50)
last_name: str = mongoz.String(max_length=50)
email: str = mongoz.Email(max_lengh=100)
password: str = mongoz.String(max_length=1000)
class Meta:
registry = registry
database = "my_db"
Como mencionado anteriormente, o Mongoz permite usar duas formas de pesquisa. Através do manager
e do queryset
.
Ambos permitem chamadas encadeadas, por exemplo, sort()
com um limit()
combinado.
Por exemplo, vamos criar um utilizador.
user = await User.objects.create(
first_name="Mongoz", last_name="ODM", email="mongoz@mongoz.com",
password="Compl3x!pa$$"
)
user = await User(
first_name="Mongoz", last_name="ODM", email="mongoz@mongoz.com",
password="Compl3x!pa$$"
).create()
Como pode verificar, o manager utiliza objects
para aceder às operações e o queryset
faz de forma diferente.
Para aqueles familiarizados com o Django, o manager
segue a mesma linha.
Agora vamos fazer uma pesquisa à base de dados para obter um registro simples, filtrando-o por email
e first_name
.
Queremos que isto retorne uma lista, já que estamos a utilizar um filter
.
users = await User.objects.filter(
email="mongoz@mongoz.com", first_name="Mongo"
)
users = await User.query(User.email == "mongoz@mongoz.com").query(
User.first_name == "Mongo"
).all()
Bastante simples, certo? Bem sim, embora preferencialmente recomendemos o uso do manager
para quase tudo o que pode fazer com o Mongoz,
às vezes usar o queryset
também pode ser útil se gosta de sintaxes diferentes. Esta sintaxe foi inspirada no Mongox.
Retornando managers/querysets¶
Existem muitas operações que pode fazer com os managers/querysets e depois também pode aproveitar essas mesmas para seus casos de uso.
Os seguintes operadores retornam managers
/querysets
, o que significa que você pode combinar diferentes operadores ao mesmo tempo.
Isso também significa que você pode aninhar vários tipos diferentes e iguais. Por exemplo:
await User.objects.filter(...).sort(...).filter(...).limit(2)
Todas as operações que retornam managers e querysets permitem chamadas combinadas/aninhadas.
Filter¶
O filtro
é exclusivo do manager
e não existe desta forma no queryset
.
A versão do queryset
é a Query.
Django-style¶
Estes filtros são as mesmas pesquisas no estilo Django.
users = await User.objects.filter(is_active=True, email__icontains="gmail")
Os mesmos operadores especiais também são adicionados automaticamente em cada coluna.
- in - O operador
IN
. - not_in - O oposto de
in
, ou seja, todos os registos que não estão na condição. - contains - Filtrar instâncias que contêm um valor específico.
- icontains - Filtrar instâncias que contêm um valor específico, sem distinguir maiúsculas de minúsculas.
- lt - Filtrar instâncias com valores "Menor Que".
- lte - Filtrar instâncias com valores "Menor or Igual Que".
- gt - Filtrar instâncias com valores "Maior Que".
- gte - Filtrar instâncias com valores "Maior ou Iugal Que".
- asc - Filtrar instâncias por ordem ascendente quando
_asc=True
. - desc - Filtrar instâncias por ordem descendente quando
_desc=True
. - neq - Filtrar instâncias por não ser igual à condição.
Example¶
users = await User.objects.filter(email__icontains="foo")
users = await User.objects.filter(id__in=[1, 2, 3])
users = await User.objects.filter(id__not_in=[1, 2, 3])
users = await User.objects.filter(id__gt=1)
users = await User.objects.filter(id__lte=3)
users = await User.objects.filter(id__lt=2)
users = await User.objects.filter(id__gte=4)
users = await User.objects.filter(id__asc=True)
users = await User.objects.filter(id__asc=False) # mesmo que desc True
users = await User.objects.filter(id__desc=True)
users = await User.objects.filter(id__desc=False) # mesmo que asc True
users = await User.objects.filter(id__neq=1) # memso que asc True
Using¶
Alterar a base de dados durante a consulta, apenas precisa fornecer o nome para alterar a base de dados de destino.
users = await User.objects.using("my_mongo_db").all()
Query¶
A query
é o que é usado pelo queryset
em vez do manager
. Noutras palavras, a query
é para o queryset
o que o filter
é para o manager
.
Um exemplo de query seria:
users = await User.query(User.email == "mongoz@mongoz.com").query(User.id > 1).all()
Ou, alternativamente, pode usar dicionários.
user = await User.query({"first_name": "Mongoz"}).all()
Ou pode usar os campos do User
em vez de dicionários.
user = await User.query({User.first_name: "Mongoz"}).all()
Limit¶
Limitar o número de resultados.
users = await User.objects.limit(1)
users = await User.objects.filter(email__icontains="mongo").limit(2)
users = await User.query().limit(1)
users = await User.query().sort(User.email, Order.ASCENDING).limit(2)
Skip¶
Saltar (ignorar) um certo número de documentos.
users = await User.objects.filter(email__icontains="mongo").skip(1)
users = await User.query().skip(1)
Raw¶
Executar pesquisas em "bruto" diretamente. Isto permite ter algum tipo de controlo sobre pesquisas mais complicadas que pode encontrar.
Consultas simples e aninhadas em bruto¶
# Simple raw query
user = await Movie.objects.raw({"email": "mongoz@mongoz.com"}).get()
users = await Movie.objects.raw({"email": "mongoz@mongoz.com"})
# Nested raw queries
user = await Movie.objects.raw({"name": "mongo"}).raw({"email": "mongoz@mongoz.com"}).get()
users = await Movie.objects.raw({"name": "mongo"}).raw({"email": "mongoz@mongoz.com"})
# Simple raw query
user = await Movie.query({"email": "mongoz@mongoz.com"}).get()
users = await Movie.query({"email": "mongoz@mongoz.com"})
# Nested raw queries
user = await Movie.query({"name": "mongo"}).raw({"email": "mongoz@mongoz.com"}).get()
users = await Movie.query({"name": "mongo"}).raw({"email": "mongoz@mongoz.com"})
Complexo com sintaxe específica do MongoDB¶
E se quiser evoluir e adicionar extras?
users = await Movie.objects.raw(
{"name": "Mongo"}).raw({"email": {"$regex": "mongo.com"}}
)
users = await Movie.objects.raw(
{"$or": [{"name": "Another Mongo"}, {"email": {"$eq": "another@mongoz.com"}}]}
)
users = await Movie.query(
{"name": "Mongo"}).raw({"email": {"$regex": "mongo.com"}}
)
users = await Movie.query(
{"$or": [{"name": "Another Mongo"}, {"email": {"$eq": "another@mongoz.com"}}]}
)
Sort¶
Ordenar os valores com base nas chaves. A ordenação, assim como qualquer retorno do manager/queryset, permite chamadas aninhadas.
# Simple and nested sorts
users = await User.objects.sort("name", Order.DESCENDING)
users = await User.objects.sort("name", Order.DESCENDING).sort("email", Order.ASCENDING)
# Using the filter
users = await User.objects.sort(name__desc=True)
users = await User.objects.sort(name__desc=True).sort(email__asc=True)
# Using a list
users = await User.objects.sort(
[(User.name, Order.DESCENDING), (User.email, Order.DESCENDING)]
)
# Simple and nested sorts
users = await User.query().sort("name", Order.DESCENDING)
users = await User.query().sort("name", Order.DESCENDING).sort("email", Order.ASCENDING)
# Using a list
users = await User.query().sort(
[(User.name, Order.DESCENDING), (User.email, Order.DESCENDING)]
)
O operador Q também permite algumas combinações se optar por esta mesma sintaxe.
Agora, é possível combinar a sintaxe do sort do queryset
com a sintaxe do sort do manager
? Sim, é possível. Um exemplo seria algo como isto:
users = await User.objects.sort(Q.desc(User.name)).sort(Q.asc(User.email)).all()
Danger
A sintaxe do queryset
é permitida dentro do manager
, mas não o contrário.
None¶
Se apenas precisar retornar um manager ou queryset vazio.
manager = await User.objects.none()
queryset = await User.query().none()
Returning results¶
Estas são as operações que retornam resultados em vez de managers ou querysets. O que significa que não é possível aninhá-las.
All¶
Retorna todas as intâncias-
users = await User.objects.all()
users = await User.objects.filter(email="mongoz@mongoz.com").all()
users = await User.query().all()
users = await User.query(User.email == "mongoz@mongoz.com").all()
Save¶
Esta é uma operação clássica que é muito útil dependendo das operações que precisa realizar. Usado para guardar um objeto existente na base de dados. Um pouco diferente do update e mais simples de ler.
await User.objects.create(is_active=True, email="foo@bar.com")
user = await User.objects.get(email="foo@bar.com")
user.email = "bar@foo.com"
await user.save()
await User(is_active=True, email="foo@bar.com").create()
user = await User.query(User.email == "foo@bar.com").get()
user.email = "bar@foo.com"
await user.save()
Agora, um cenário mais único, mas possível, com um save. Imagine que precisa criar uma cópia exata de um objeto e guardá-lo na base de dados. Estes casos são mais comuns do que imagina, mas este exemplo é apenas para fins ilustrativos.
await User.objects.create(is_active=True, email="foo@bar.com", name="John Doe")
user = await User.objects.get(email="foo@bar.com")
# User(id=ObjectId(...))
# Making a quick copy
user.id = None
new_user = await user.save()
# User(id=ObjectId(...))
await User(is_active=True, email="foo@bar.com", name="John Doe").create()
user = await User.query(User.email == "foo@bar.com").get()
# User(id=ObjectId(...))
# Making a quick copy
user.id = None
new_user = await user.save()
# User(id=ObjectId(...))
Delete¶
Usado para eliminar uma instância.
await User.objects.filter(email="foo@bar.com").delete()
await Movie.query({User.email: "foo@bar.com"}).delete()
Ou diretamente na instância.
user = await User.objects.get(email="foo@bar.com")
await user.delete()
await Movie.query({User.email: "foo@bar.com"}).delete()
await user.delete()
Update¶
Pode atualizar instâncias de documentos chamando este operador.
user = await User.objects.get(email="foo@bar.com")
await user.update(email="bar@foo.com")
user = await User.query(User.email == "foo@bar.com").get()
await user.update(email="bar@foo.com")
Também existe a possibilidade de atualizar todos os registos com base numa pesquisa específica.
user = await User.objects.filter(id__gt=1).update(name="MongoZ")
user = await User.objects.filter(id__gt=1).update_many(name="MongoZ")
user = await User.query(User.id > 1).update(name="MongoZ")
user = await User.query(User.id > 1).update_many(name="MongoZ")
Get¶
Obtém um único registo da base de dados.
user = await User.objects.get(email="foo@bar.com", name="Mongoz")
user = await User.query(User.email == "foo@bar.com").query(User.name == "Mongoz").get()
Também é possível combinar os resultados do queryset com este operador.
user = await User.objects.filter(email="foo@bar.com").get()
user = await User.query().query(User.email == "foo@bar.com").get()
First¶
Quando precisar retornar o primeiro resultado de um queryset.
user = await User.objects.first()
user = await User.query().first()
Também é possível aplicar filtros quando necessário.
user = await User.objects.filter(email="foo@bar.com").first()
user = await User.query(User.email == "foo@bar.com").first()
Last¶
Quando precisar retornar o último resultado de um queryset.
user = await User.objects.last()
user = await User.query().last()
Também é possível aplicar filtros quando necessário.
user = await User.objects.filter(name="mongoz").last()
user = await User.query(User.email == "mongoz").last()
Count¶
Retorna um número inteiro com o total de registos.
total = await User.objects.count()
total = await User.query().count()
Exclude¶
O exclude()
é usado quando deseja filtrar os resultados excluindo instâncias.
users = await User.objects.exclude(is_active=False)
users = await User.query(Q.not_(User.is_active, False)).all()
Com o queryset, simplesmente chamamos o operador Not.
Values¶
Retorna os resultados do modelo num formato de dicionário.
await User.objects.create(name="John" email="foo@bar.com")
# All values
user = User.objects.values()
users == [
{"id": 1, "name": "John", "email": "foo@bar.com"},
]
# Only the name
user = User.objects.values("name")
users == [
{"name": "John"},
]
# Or as a list
# Only the name
user = User.objects.values(["name"])
users == [
{"name": "John"},
]
# Exclude some values
user = User.objects.values(exclude=["id"])
users == [
{"name": "John", "email": "foo@bar.com"},
]
await User(name="John" email="foo@bar.com").create()
# All values
user = User.query().values()
users == [
{"id": 1, "name": "John", "email": "foo@bar.com"},
]
# Only the name
user = User.query().values("name")
users == [
{"name": "John"},
]
# Or as a list
# Only the name
user = User.query().values(["name"])
users == [
{"name": "John"},
]
# Exclude some values
user = User.query().values(exclude=["id"])
users == [
{"name": "John", "email": "foo@bar.com"},
]
O values()
também pode ser combinado com filter
, only
como de costume.
Parâmetros:
- fields - Campos a retornar.
- exclude - Campos a excluir do retorno.
- exclude_none - Sinalizador booleano indicando se os campos com
None
devem ser excluídos.
Values list¶
Retorna os resultados do modelo nm formato de tuplo.
await User.objects.create(name="John" email="foo@bar.com")
# All values
user = User.objects.values_list()
users == [
(1, "John" "foo@bar.com"),
]
# Only the name
user = User.objects.values_list("name")
users == [
("John",),
]
# Or as a list
# Only the name
user = User.objects.values_list(["name"])
users == [
("John",),
]
# Exclude some values
user = User.objects.values(exclude=["id"])
users == [
("John", "foo@bar.com"),
]
# Flattened
user = User.objects.values_list("email", flat=True)
users == [
"foo@bar.com",
]
await User(name="John" email="foo@bar.com").create()
# All values
user = User.query().values_list()
users == [
(1, "John" "foo@bar.com"),
]
# Only the name
user = User.query().values_list("name")
users == [
("John",),
]
# Or as a list
# Only the name
user = User.query().values_list(["name"])
users == [
("John",),
]
# Exclude some values
user = User.query().values(exclude=["id"])
users == [
("John", "foo@bar.com"),
]
# Flattened
user = User.query().values_list("email", flat=True)
users == [
"foo@bar.com",
]
O método values_list()
também pode ser combinado com filter
, only
como de costume.
Parâmetros:
- fields - Campos a retornar.
- exclude - Campos a excluir do retorno.
- exclude_none - Sinalizador booleano indicando se os campos com
None
devem ser excluídos. - flat - Sinalizador booleano indicando se os resultados devem ser achatados.
Only¶
Retorna os resultados contendo apenas os campos na pesquisa e nada mais.
await User.objects.create(name="John" email="foo@bar.com")
user = await User.objects.only("name")
await User(name="John" email="foo@bar.com").create
user = await User.query().only("name").all()
Warning
Só pode utilizar only()
ou defer()
, mas não ambos combinados, caso contrário, será lançado um FieldDefinitionError
.
Defer¶
Retorna os resultados contendo todos os campos excepto aqueles que deseja excluir.
await User.objects.create(name="John" email="foo@bar.com")
user = await User.objects.defer("name")
await User(name="John" email="foo@bar.com").create
user = await User.query().defer("name").all()
Warning
Só pode utilizar only()
ou defer()
, mas não ambos combinados, caso contrário, será lançado um FieldDefinitionError
.
Get or none¶
Ao pesquisar um documento e não desejar obter um DocumentNotFound e, em vez disso, retornar None
.
user = await User.objects.get_or_none(id=1)
user = await User.query(User.id == 1).get_or_none()
Where¶
Aplicar pesquisas de strings em bruto ou a cláusula where
.
user = await User.objects.where("this.email == 'foo@bar.com'")
user = await User.query().where("this.email == 'foo@bar.com'")
Distinct values¶
Filtrar por valores distintos e retornar uma lista desses mesmos valores.
user = await User.objects.distinct_values("email")
user = await User.query().distinct_values("email")
Get document by id¶
Obter um documento pelo _id
. Esta funcionalidade aceita o parâmetro id
como uma string ou bson.ObjectId
.
user = await User.objects.create(
first_name="Foo", last_name="Bar", email="foo@bar.com"
)
user = await User.objects.get_document_by_id(user.id)
user = await User(
first_name="Foo", last_name="Bar", email="foo@bar.com"
).create()
user = await User.query().get_document_by_id(user.id)
Exists¶
O exists()
é utilizado quando deseja verificar se um registro existe na base de dados ou não.
await User.objects.exists(email="example@example.com", is_active=False)
await User.objects.filter(email="example@example.com", is_active=False).exists()
Métodos úteis¶
Get or create¶
Quando precisar obter uma instância existente de um documento a partir de uma consulta correspondente. Se existir, retorna ou cria uma nova caso não exista.
user = await User.objects.get_or_create(email="foo@bar.com", defaults={
"is_active": False, "first_name": "Foo"
})
user = await User.query().get_or_create(
{User.is_active: False, User.first_name: "Foo", User.email: "foo@bar.com"}
)
Isto irá pesquisar o documento User
com o email
como chave de pesquisa. Se não existir, então irá utilizar esse valor com os defaults
fornecidos para criar uma nova instância.
Bulk create¶
Quando precisar criar várias instâncias de uma só vez, ou em massa
.
user_names = ("MongoZ", "MongoDB")
models = [
User(first_name=name, last_name=name, email=f"{name}@mongoz.com") for name in user_names
]
users = await User.objects.bulk_create(models)
user_names = ("MongoZ", "MongoDB")
models = [
User(first_name=name, last_name=name, email=f"{name}@mongoz.com") for name in user_names
]
users = await User.query().bulk_create(models)
Bulk update¶
Quando precisar atualizar várias instâncias de uma só vez, ou em massa
.
data = [
{"email": "foo@bar.com", "first_name": "Foo", "last_name": "Bar", "is_active": True},
{"email": "bar@foo.com", "first_name": "Bar", "last_name": "Foo", "is_active": True}
]
users = [User(**user_data.model_dump()) for user_data in data]
await User.objects.bulk_create(users)
users = await User.objects.all()
await User.objects.filter().bulk_update(is_active=False)
data = [
{"email": "foo@bar.com", "first_name": "Foo", "last_name": "Bar", "is_active": True},
{"email": "bar@foo.com", "first_name": "Bar", "last_name": "Foo", "is_active": True}
]
users = [User(**user_data.model_dump()) for user_data in data]
await User.objects.bulk_create(users)
users = await User.objects.all()
await User.query().bulk_update(is_active=False)
Nota¶
Quando aplicar as funções que retornam valores diretamente e não managers ou querysets,
ainda é possível aplicar os operadores como filter
, skip
, sort
...
Consultar documentos incorporados¶
Consultar documentos incorporados também é fácil e aqui o queryset
é muito poderoso para fazê-lo.
Vamos ver um exemplo.
import mongoz
database_uri = "mongodb://localhost:27017"
registry = mongoz.Registry(database_uri)
class UserType(mongoz.EmbeddedDocument):
level: str = mongoz.String()
class User(mongoz.Document):
is_active: bool = mongoz.Boolean(default=True)
first_name: str = mongoz.String(max_length=50)
last_name: str = mongoz.String(max_length=50)
email: str = mongoz.Email(max_lengh=100)
password: str = mongoz.String(max_length=1000)
user_type: UserType = mongoz.Embed(UserType)
class Meta:
registry = registry
database = "my_db"
Agora podemos criar algumas instâncias do User
.
access_type = UserType(access_level="admin")
await User.objects.create(
first_name="Mongoz", last_name="ODM", email="mongoz@mongoz.com",
access_level=access_type
)
access_type = UserType(access_level="admin")
await User(
first_name="Mongoz", last_name="ODM", email="mongoz@mongoz.com",
access_level=access_type
).create()
Isto irá criar o seguinte documento na base de dados:
{
"email": "mongoz@mongoz.com", "first_name": "Mongoz", "last_name": "ODM",
"is_active": true, "access_level": {"level": "admin" }
},
Agora é possível pesquisar o utilizador pelo campo do documento incorporado.
await User.query(User.user_type.level == "admin").get()
Este é o equivalente ao seguinte filtro:
{"access_level.level": "admin" }
Também pode utilizar o documento incorporado completo.
await User.query(User.user_type == level).get()
Este é o equivalente ao seguinte filtro:
{"access_level": {"level": "admin"} }
Warning
Para o tipo de pesquisa Documentos Incorporados, usando o manager não irá funcionar.
Deve-se usar a abordagem do tipo queryset
para a pesquisa.
O operador Q¶
Este operador foi inspirado pelo Mongox
e estendido para as necessidades do Mongoz. O crédito pelo design inicial do operador Q
vai para o Mongox
.
A classe Q
contém alguns métodos úteis e bastante práticos para serem usados nas pesquisas.
from mongoz import Q, Order
O operador Q
é principalmente usado no queryset
e não tanto no manager
, e a principal razão para isso é porque o manager
manipula internamente o operador Q
automaticamente. Bem porreiro, não é?
Para criar, por exemplo, uma pesquisa de sort
, normalmente faria assim:
users = await User.query().sort(User.email, Order.DESCENDING).all()
Onde é que o operador Q
entra aqui? Bem, pode ser visto como um atalho para as suas pesquisas.
Ascending¶
users = await User.query().sort(Q.asc(User.email)).all()
Descending¶
users = await User.query().sort(Q.desc(User.email)).all()
In¶
O operados in
.
users = await User.query(Q.in_(User.id, [1, 2, 3, 4])).all()
Not In¶
O operador not_in
.
users = await User.query(Q.not_in(User.id, [1, 2, 3, 4])).all()
And¶
users = await User.query(Q.and_(User.email == "foo@bar.com", User.id > 1)).all()
users = await User.query(User.email == "foo@bar.com").query(User.id > 1).all()
Or¶
users = await User.query(Q.or_(User.email == "foo@bar.com", User.id > 1)).all()
Nor¶
users = await User.query(Q.nor_(User.email == "foo@bar.com", User.id > 1)).all()
Not¶
users = await User.query(Q.not_(User.email, "foo@bar.com")).all()
Contains¶
users = await User.query(Q.contains(User.email, "foo")).all()
IContains¶
users = await User.query(Q.icontains(User.email, "foo")).all()
Padrão¶
Aplica alguns padrões $regex
.
users = await User.query(Q.pattern(User.email, r"\w+ foo \w+")).all()
Igual¶
O operador equals
.
users = await User.query(Q.eq(User.email, "foo@bar.com")).all()
Diferente¶
O operador not equals
.
users = await User.query(Q.neq(User.email, "foo@bar.com")).all()
Where¶
Aplicando o operador where
do MongoDB.
users = await User.query(Q.where(User.email, "foo@bar.com")).all()
Maior do que¶
users = await User.query(Q.gt(User.id, 1)).all()
Maior ou Igual que¶
users = await User.query(Q.gte(User.id, 1)).all()
Menor do que¶
users = await User.query(Q.lt(User.id, 20)).all()
Menor ou Igual que¶
users = await User.query(Q.lte(User.id, 20)).all()
Queries blocking¶
O que acontece se você quiser usar o Mongoz com uma operação blocking? Por blocking, entende-se "síncrono". Por exemplo, o Flask não suporta nativamente operações "assíncronas" e o Mongoz é um ODM assíncrono agnóstico e provavelmente gostaria de aproveitar o Mongoz, mas sem fazer muita magia nos bastidores.
Bem, o Mongoz também suporta a funcionalidade run_sync
que permite executar as consultas em modo
blocking com facilidade!
Como utilizar¶
Simplesmente precisa utilizar a funcionalidade run_sync
do Mongoz e torná-la quase imediata.
from mongoz import run_sync
Todas as funcionalidades disponíveis do Mongoz são executadas dentro deste invólucro sem sintaxe extra.
Vejamos alguns exemplos.
Modo async
await User.objects.all()
await User.objects.filter(name__icontains="example")
await User.objects.create(name="Mongoz")
Com run_sync
from mongoz import run_sync
run_sync(User.objects.filter(name__icontains="example"))
run_sync(User.objects.create(name="Mongoz"))