len()
, count()
, etc. Asegúrese de hacer el mejor uso de ellos.
# models.py from django.db import models class Sale(models.Model): sold_at = models.DateTimeField( auto_now_add=True, ) charged_amount = models.PositiveIntegerField()
# models.py from django.db import models class Sale(models.Model): sold_at = models.DateTimeField( auto_now_add=True, db_index=True, #DB Indexing ) charged_amount = models.PositiveIntegerField()
# models.py from django.db import models class Sale(models.Model): sold_at = models.DateTimeField( auto_now_add=True, db_index=True, #DB Indexing ) charged_amount = models.PositiveIntegerField() class Meta: indexes = [ ["sold_at", "charged_amount"]]
ip:port
donde ip
es la dirección IP del daemon de Memcached y port
es el puerto en el que se ejecuta Memcached, o la URL que apunta a su instancia de Redis, usando el esquema apropiado.
Para habilitar el almacenamiento en caché de la base de datos con Memcached, instale pymemcache
usando pip usando el siguiente comando:
pip install pymemcache
Luego, puede configurar los ajustes de caché en su settings.py
de la siguiente manera:
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache', 'LOCATION': '127.0.0.1:11211', } }
En el ejemplo anterior, Memcached se ejecuta en el puerto localhost (127.0.0.1) 11211, utilizando el enlace pymemcache
:
pip install redis
Luego configure los ajustes de caché en su settings.py
agregando el siguiente código:
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.redis.RedisCache', 'LOCATION': 'redis://127.0.0.1:6379', } }
Un conjunto de consultas en Django, por lo general, almacena en caché su resultado cuando ocurre la evaluación y para cualquier otra operación con ese conjunto de consultas, primero verifica si hay resultados almacenados en caché. Sin embargo, cuando usa iterator()
, no verifica el caché y lee los resultados directamente de la base de datos, ni guarda los resultados en el conjunto de consultas.
Ahora, usted debe estar preguntándose cómo esto es útil. Considere un conjunto de consultas que devuelve una gran cantidad de objetos con mucha memoria para almacenar en caché, pero debe usarse solo una vez, en tal caso, debe usar un iterator()
.
queryset = Product.objects.all() for each in queryset: do_something(each)
Mientras que si usamos iterator()
, Django mantendrá abierta la conexión SQL y leerá cada registro, y llamará a do_something()
antes de leer el siguiente registro:
queryset = Product.objects.all().iterator() for each in queryset: do_something(each)
Django crea una nueva conexión de base de datos para cada solicitud y la cierra una vez que se completa la solicitud. Este comportamiento es causado por CONN_MAX_AGE
, que tiene un valor predeterminado de 0. Pero, ¿cuánto tiempo debe configurarse? Eso está determinado por el volumen de tráfico en su sitio; cuanto mayor sea el volumen, más segundos se requieren para mantener la conexión. Por lo general, se recomienda comenzar con un número bajo, como 60.
Debe envolver sus opciones adicionales en OPTIONS
, como se detalla en el
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'dashboard', 'USER': 'root', 'PASSWORD': 'root', 'HOST': '127.0.0.1', 'PORT': '3306', 'OPTIONS': { 'CONN_MAX_AGE': '60', } } }
Nota: estas expresiones están definidas en django.db.models.expressions
y django.db.models.aggregates
, pero por conveniencia, están disponibles y normalmente se importan desde django.db.models
.
En la API de Django Queryset, las expresiones F()
se utilizan para referirse directamente a los valores de campo del modelo. Le permite hacer referencia a los valores de los campos del modelo y realizar acciones en la base de datos sobre ellos sin tener que buscarlos en la base de datos y en la memoria de Python. En su lugar, Django emplea el objeto F()
para producir una frase SQL que define la actividad necesaria de la base de datos.
products = Product.objects.all() for product in products: product.price *= 1.2 product.save()
Sin embargo, si usamos F()
, podemos hacer esto en una sola consulta de la siguiente manera:
from django.db.models import F Product.objects.update(price=F('price') * 1.2)
select_related()
y prefetch_related()
Django proporciona select_related()
y prefetch_related()
para optimizar sus conjuntos de consultas al minimizar el número de solicitudes de base de datos.
select_related()
"sigue" las relaciones de clave externa, seleccionando datos adicionales de objetos relacionados cuando ejecuta su consulta.
prefetch_related()
realiza una búsqueda separada para cada relación y realiza la "unión" en Python.
select_related()
Usamos select_related()
cuando el elemento que se va a seleccionar es un solo objeto, lo que significa un campo ForeignKey
hacia adelante, OneToOne
y OneToOne
hacia atrás.
Puede usar select_related()
para crear una sola consulta que devuelva todos los objetos relacionados para una sola instancia para conexiones uno-muchos y uno-a-uno. Cuando se realiza la consulta, select_related()
recupera cualquier dato adicional de objeto relacionado de las relaciones de clave externa.
select_related()
funciona generando una unión SQL e incluye las columnas del objeto relacionado en la expresión SELECT
. Como resultado, select_related()
devuelve elementos relacionados en la misma consulta de base de datos.
Aunque select_related()
produce una consulta más sofisticada, los datos adquiridos se almacenan en caché, por lo que el manejo de los datos obtenidos no requiere ninguna solicitud de base de datos adicional.
queryset = Tweet.objects.select_related('owner').all()
prefetch_related()
Por el contrario, prefetch_related()
se utiliza para conexiones de muchos a muchos y de muchos a uno. Produce una sola consulta que incluye todos los modelos y filtros que se proporcionan en la consulta.
Book.objects.prefetch_related('author').get(id=1).author.first_name
Lea sobre la diferencia entre select_related()
y prefetch_related()
en detalle .
bulk_create()
y bulk_update()
bulk_create()
es un método que crea la lista de objetos proporcionada en la base de datos con una consulta. De manera similar, bulk_update()
es un método que actualiza los campos dados en las instancias del modelo proporcionadas con una consulta.
class Post(models.Model): title = models.CharField(max_length=300, unique=True) time = models.DateTimeField(auto_now_add=True) def __str__(self): return self.title
Ahora, digamos que queremos agregar múltiples registros de datos a este modelo, entonces podemos usar bulk_create()
así:
#articles articles = [Post(title="Hello python"), Post(title="Hello django"), Post(title="Hello bulk")] #insert data Post.objects.bulk_create(articles)
>>> Post.objects.all() <QuerySet [<Post: Hello python>, <Post: Hello django>, <Post: Hello bulk>]>
Y si queremos actualizar los datos, podemos usar bulk_update()
así:
update_queries = [] a = Post.objects.get(id=14) b = Post.objects.get(id=15) c = Post.objects.get(id=16) #set update value a.title="Hello python updated" b.title="Hello django updated" c.title="Hello bulk updated" #append update_queries.extend((a, b, c)) Post.objects.bulk_update(update_queries, ['title'])
>>> Post.objects.all() <QuerySet [<Post: Hello python updated>, <Post: Hello django updated>, <Post: Hello bulk updated>]>