2010-07-02 4 views
2

Contexte: J'ai restauré la base de données à partir d'une sauvegarde SQL plusieurs fois Exécution d'une base de données PostgreSQL pour une application Django (Django 1.1.1, python2.4, et de psycopg2 Postgres 8.1). Chaque fois que je fais ça, puis essayer d'ajouter une nouvelle ligne, soit shell, admin, ou d'un site frontal, je reçois cette erreur:Django ORM interprète les séquences PostgreSQL?

IntegrityError: duplicate key violates unique constraint "app_model_pkey"

La décharge de données est très bien et est remise à zéro des séquences. Mais si j'essaye d'ajouter de nouveau la ligne, c'est réussi! Donc, je peux juste essayer de brouiller une nouvelle ligne dans chaque table, puis tout semble être copacétique.

Question: Étant donné que (1) la décharge SQL est bon et Postgres est en train de lire dans correctement (par earlier question), et (2) ORM de Django ne semble pas échouer systématiquement obtenir les valeurs suivantes, ce qui se passe dans ce cas précis?

Répondre

1

Django ne détient pas ou lire directement les valeurs de séquence en aucune façon. Je l'ai expliqué en this question: 2088210/django-object-creation-and-postgres-sequences. Postgresql incrémente la séquence lorsque vous tentez d'ajouter une ligne, même si le résultat de l'opération échoue (une erreur de clé dupliquée est générée). L'incrémentation de la séquence ne s'annule pas. Donc, c'est la raison pour laquelle cela fonctionne la deuxième fois que vous essayez d'ajouter une ligne. Je ne sais pas pourquoi vos séquences ne sont pas définies correctement, pourriez-vous vérifier quelle est la valeur de la séquence avant le vidage et après la restauration, et faire la même chose avec le max() pk de la table? Peut-être que c'est un bug 8.1 avec la restauration? Je ne sais pas. Ce dont je suis sûr: ce n'est pas la faute de Django.

+0

Je voudrais compris pourquoi, mais cela semble être la réponse. Je n'avais qu'un seul groupe d'auth, et la sauvegarde définissait la valeur actuelle de la séquence de cet ID à 1: 'SELECT pg_catalog.setval ('auth_group_id_seq', 1, false);'. Si j'essaie de sélectionner le nextval de cette séquence, c'est également 1. La requête suivante pour nextval envoie la séquence à 2. – bennylope

+0

C'est incorrect; Django récupère en effet les valeurs des séquences PostgreSQL. Si vous activez la consignation de toutes les instructions dans votre base de données, vous verrez que Django émet un certain nombre de commandes 'SELECT CURRVAL ('" app_table_id_seq "');' En fait, si vous regardez le code de 'django.db.models.sql.compiler.SQLInsertCompiler.execute_sql()' et 'django.db.backends.postgresql.operations.DatabaseOperations.last_insert_id()', youll voir que récupère la valeur de la séquence après chaque commande INSERT à moins que 'autocommit = True'. –

2

Je suppose que votre séquence est obsolète.

Vous pouvez corriger cela comme ceci:

select setval('app_model_id_seq', max(id)) from app_model; 
Questions connexes