es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

El crecimiento de mi ID en Django ORM no es lineal cuando guardo los datos en el modelo.

En mi proyecto de Django, tengo un comportamiento muy extraño en un modelo relacionado con los valores del campo de identificación primaria en la base de datos. Tengo este modelo:

class Results(models.Model):
    id = models.AutoField(primary_key=True)
    device = models.ForeignKey(Device, null=True, on_delete=models.SET_NULL)
    proj_code = models.CharField(max_length=400)
    res_key = models.SlugField(max_length=80, verbose_name="Clave única del mensaje", unique=True)
    read_date = models.DateTimeField(verbose_name="Fecha y hora de lecturas de valores")
    unit = models.ForeignKey(ModbusDevice, null=True, on_delete=models.SET_NULL)

    def __str__(self):
        return self.device

    class Meta:
        indexes = [
            models.Index(fields=['device', 'unit', 'proj_code', 'read_date']),
        ]

Bueno, en un archivo .py guardo datos en esta tabla de la siguiente manera:

try:
    p = Results(device=Device.objects.get(mac_id=macid),
        proj_code=projid,
        res_key=datalist[x]['key'],
        read_date=topic_date,
        unit=unit_ck)

     p.save()
except IntegrityError as e:
     if 'UNIQUE constraint' not in e.args[0]:
         pass
except ObjectDoesNotExist:
    pass

Por lo tanto, los datos se guardaron en la base de datos, pero si inspecciono el campo “id”, observo comportamientos extraños como estos:

|id|Otros...
|1 |datos
|2 |datos
|3 |datos
|11|datos
|12|datos
!99|datos

Mi campo en la base de datos PostgreSql está configurado como se muestra en esta imagen:

Configuración del campo en la base de datos

No sé por qué, pero mi identificación no crece de manera lineal como esperaba. ¿Alguien ha experimentado el mismo comportamiento? ¿Cómo puedo forzar el crecimiento lineal de la identificación al guardar los datos?

Muchas gracias de antemano
Manuel

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Parece que tu problema está relacionado con los valores de secuencia en Postgres. Por defecto, Django utiliza una secuencia para generar valores de clave primaria para los tipos de datos AutoField. Estas secuencias pueden estar en caché y no siempre generan valores en un orden lineal.

    Para forzar el guardado de datos con un crecimiento lineal de identificadores, puedes resetear el valor de la secuencia en Postgres utilizando la función setval. Puedes conectarte a tu instancia de Postgres utilizando una herramienta como psql y ejecutar el siguiente comando:

    SELECT setval('results_id_seq', (SELECT MAX(id) FROM results));
    

    Este comando reseteará el generador de secuencia para el campo id en la tabla results al valor máximo del campo id en la tabla.

    Alternativamente, puedes definir una secuencia personalizada para la generación de claves primarias en la definición de tu modelo. Por ejemplo:

    from django.db import models
    from django.db.models import Max
    
    class Results(models.Model):
        id = models.IntegerField(primary_key=True)
        # ...
    
        def save(self, *args, **kwargs):
            if not self.id:
                self.id = Results.objects.all().aggregate(Max('id'))['id__max'] + 1 or 1
            super().save(*args, **kwargs)
    

    En este ejemplo, definimos un IntegerField personalizado para el campo id y sobrescribimos el método save para establecer el valor de id como el valor máximo de id en la tabla más uno. Esto asegurará que los valores de id se generen en un orden lineal.

Comments are closed.