Saltar al contenido

Django: save() vs update() para actualizar la base de datos?

Si encuentras algo que no entiendes puedes dejarnos un comentario y trataremos de ayudarte lo más rápido posible.

Solución:

Hay varios key diferencias

update se utiliza en un conjunto de consultas, por lo que es posible actualizar varios objetos a la vez.

Como señaló @FallenAngel, hay diferencias en cómo personalizar save() disparadores del método, pero también es importante tener en cuenta signals y ModelManagers. He creado una pequeña aplicación de prueba para mostrar algunas diferencias valiosas. Estoy usando Python 2.7.5, Django==1.7.7 y SQLite, tenga en cuenta que los SQL finales pueden variar en diferentes versiones de Django y diferentes motores de base de datos.

Bien, aquí está el código de ejemplo.

models.py:

from __future__ import print_function
from django.db import models
from django.db.models import signals
from django.db.models.signals import pre_save, post_save
from django.dispatch import receiver

__author__ = 'sobolevn'

class CustomManager(models.Manager):
    def get_queryset(self):
        super_query = super(models.Manager, self).get_queryset()
        print('Manager is called', super_query)
        return super_query


class ExtraObject(models.Model):
    name = models.CharField(max_length=30)

    def __unicode__(self):
        return self.name


class TestModel(models.Model):

    name = models.CharField(max_length=30)
    key = models.ForeignKey('ExtraObject')
    many = models.ManyToManyField('ExtraObject', related_name='extras')

    objects = CustomManager()

    def save(self, *args, **kwargs):
        print('save() is called.')
        super(TestModel, self).save(*args, **kwargs)

    def __unicode__(self):
        # Never do such things (access by foreing key) in real life,
        # because it hits the database.
        return u'  '.format(self.name, self.key.name, self.many.count())


@receiver(pre_save, sender=TestModel)
@receiver(post_save, sender=TestModel)
def reicever(*args, **kwargs):
    print('signal dispatched')

views.py:

def index(request):
    if request and request.method == 'GET':

        from models import ExtraObject, TestModel

        # Create exmple data if table is empty:
        if TestModel.objects.count() == 0:
            for i in range(15):
                extra = ExtraObject.objects.create(name=str(i))
                test = TestModel.objects.create(key=extra, name='test_%d' % i)
                test.many.add(test)
                print test

        to_edit = TestModel.objects.get(id=1)
        to_edit.name = 'edited_test'
        to_edit.key = ExtraObject.objects.create(name='new_for')
        to_edit.save()

        new_key = ExtraObject.objects.create(name='new_for_update')
        to_update = TestModel.objects.filter(id=2).update(name='updated_name', key=new_key)
        # return any kind of HttpResponse

Eso resultó en estas consultas SQL:

# to_edit = TestModel.objects.get(id=1):
QUERY = u'SELECT "main_testmodel"."id", "main_testmodel"."name", "main_testmodel"."key_id" 
FROM "main_testmodel" 
WHERE "main_testmodel"."id" = %s LIMIT 21' 
- PARAMS = (u'1',)

# to_edit.save():
QUERY = u'UPDATE "main_testmodel" SET "name" = %s, "key_id" = %s 
WHERE "main_testmodel"."id" = %s' 
- PARAMS = (u"'edited_test'", u'2', u'1')

# to_update = TestModel.objects.filter(id=2).update(name='updated_name', key=new_key):
QUERY = u'UPDATE "main_testmodel" SET "name" = %s, "key_id" = %s 
WHERE "main_testmodel"."id" = %s' 
- PARAMS = (u"'updated_name'", u'3', u'2')

Solo tenemos una consulta para update() y dos para save().

A continuación, hablemos de anular save() método. Se llama una sola vez para save() método obviamente. Vale la pena mencionar que .objects.create() también llama save() método.

Pero update() no llama save() en modelos. y si no save() se pide el metodo update(), por lo que las señales tampoco se disparan. Producción:

Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

# TestModel.objects.get(id=1):
Manager is called []
Manager is called []
save() is called.
signal dispatched
signal dispatched

# to_update = TestModel.objects.filter(id=2).update(name='updated_name', key=new_key):
Manager is called []

Como puedes ver save() disparadores Manager‘s get_queryset() dos veces. Cuándo update() sólo una vez.

Resolución. Si necesita actualizar “silenciosamente” sus valores, sin save() sido llamado – uso update. Casos de uso: last_seen campo del usuario. Cuando necesite actualizar su modelo correctamente, use save().

Ambos parecen similares, pero hay algunos key puntos:

  1. save() activará cualquier anulado Model.save() método, pero update() no activará esto y realizará una actualización directa en el nivel de la base de datos. Entonces, si tiene algunos modelos con métodos de guardado anulados, debe evitar usar la actualización o encontrar otra forma de hacer lo que está haciendo en ese anulado. save() métodos.

  2. obj.save() puede tener algunos efectos secundarios si no tiene cuidado. Recuperas el objeto con get(...) y todos los valores de campo del modelo se pasan a su obj. Cuando usted llama obj.save(), django guardará el estado actual del objeto para grabar. Entonces, si ocurren algunos cambios entre get() y save() por algún otro proceso, entonces esos cambios se perderán. utilizar save(update_fields=[.....]) por evitar este tipo de problemas.

  3. Antes de la versión 1.5 de Django, Django estaba ejecutando un SELECT antes de INSERT/UPDATE, por lo que cuesta 2 consultas de ejecución. Con la versión 1.5, ese método está obsoleto.

Aquí hay una buena guía o save() y update() métodos y cómo se ejecutan.

El método save () se puede usar para insertar un nuevo registro y actualizar el registro existente y generalmente se usa para guardar instancias de un solo registro (fila en mysql) en la base de datos.

update() no se usa para insertar registros y se puede usar para actualizar varios registros (filas en mysql) en la base de datos.

Aquí tienes las comentarios y calificaciones

Si piensas que te ha resultado provechoso nuestro post, sería de mucha ayuda si lo compartes con más programadores de este modo nos ayudas a dar difusión a nuestra información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *