Je travaille sur une version hors ligne de mon application Web Django et j'ai fréquemment supprimé des instances de modèle pour un certain ModelX.
Je l'ai fait à partir de la page d'administration et je n'ai rencontré aucun problème. Le modèle n'a que deux champs: nom et ordre et aucune autre relation avec d'autres modèles.
Les nouvelles instances reçoivent le prochain pk disponible, ce qui est logique, et lorsque j'ai supprimé toutes les instances, l'ajout d'une nouvelle instance donne un pk = 1, ce que j'attends.
En déplaçant le code en ligne dans ma base de données réelle, j'ai remarqué que ce n'était pas le cas. Je devais changer les instances du modèle, je les ai donc toutes supprimées, mais à ma grande surprise, les clés primaires ont continué à incrémenter sans revenir à 1.
Entrer dans la base de données à l'aide de l'API Django j'ai vérifié et les anciennes instances ont disparu, mais même l'ajout de nouvelles instances donne une clé primaire qui reprend là où la dernière instance supprimée s'est arrêtée, au lieu de 1 .
Vous vous demandez si quelqu'un sait quel pourrait être le problème ici.
Comme d'autres l'ont indiqué, cette responsabilité incombe entièrement à la base de données.
Mais vous devez comprendre que c'est le comportement souhaitable. Un ID identifie de manière unique une entité dans votre base de données. En tant que tel, il ne doit faire référence qu'à une seule ligne. Si cette ligne est supprimée par la suite, il n'y a aucune raison pour que vous souhaitiez qu'une nouvelle ligne réutilise cet ID: si vous faisiez cela, vous créeriez une confusion entre l'entité maintenant supprimée qui avait cet ID et le nouvellement créé qui l'a réutilisé. Cela ne sert à rien et vous ne devriez pas vouloir le faire.
Je n'appellerais pas ça un problème. Il s'agit d'un comportement par défaut pour de nombreux systèmes de base de données. Fondamentalement, le compteur d'incrémentation automatique d'une table est persistant et la suppression d'entrées n'affecte pas le compteur. La valeur réelle de la clé primaire n'affecte pas les performances ou quoi que ce soit, elle n'a qu'une valeur esthétique (si vous atteignez la limite de 2 milliards, vous aurez probablement d'autres problèmes à vous soucier).
Si vous voulez vraiment réinitialiser le compteur, vous pouvez supprimer et recréer le tableau:
python manage.py sqlclear <app_name> > python manage.py dbshell
Ou, si vous devez conserver les données d'autres tables dans l'application, vous pouvez réinitialiser manuellement le compteur:
python manage.py dbshell
mysql> ALTER TABLE <table_name> AUTO_INCREMENT = 1;
La raison la plus probable pour laquelle vous voyez un comportement différent dans vos applications hors ligne et en ligne est que la valeur d'incrémentation automatique est uniquement stockée en mémoire, pas sur le disque. Il est recalculé comme MAX(<column>) + 1
à chaque redémarrage du serveur de base de données. Si la table est vide, elle sera complètement réinitialisée au redémarrage. C'est probablement très souvent pour votre environnement hors ligne et presque nul pour votre environnement en ligne.
Les avez-vous réellement supprimés de votre base de données ou les avez-vous supprimés à l'aide de Django? Django ne changera pas AUTO_INCREMENT
pour votre table simplement en supprimant des lignes, donc si vous voulez réinitialiser vos clés primaires, vous devrez peut-être aller dans votre base de données et:
ALTER TABLE <my-table> AUTO_INCREMENT = 1;
(Cela suppose que vous utilisez MySQL ou similaire).
Il n'y a pas de problème, c'est ainsi que fonctionnent les bases de données. Django n'a rien à voir avec la génération d'ID, il indique simplement à la base de données d'insérer une ligne et obtient l'ID en réponse à partir de la base de données. L'ID commence à 1 pour chaque table et s'incrémente à chaque fois vous insérez une ligne. La suppression de lignes ne fait pas reculer l'ID. Vous ne devriez généralement pas vous en préoccuper, tout ce que vous devez savoir, c'est que chaque ligne a un identifiant unique.
Vous pouvez bien sûr changer le compteur qui génère l'identifiant de votre table avec une commande de base de données et cela dépend du système de base de données spécifique que vous utilisez.
Si vous utilisez SQLite, vous pouvez réinitialiser la clé primaire avec les commandes Shell suivantes:
SUPPRIMER DE votre_table; SUPPRIMER DE SQLite_sequence WHERE name = 'your_table';
Je ne sais pas quand cela a été ajouté, mais la commande de gestion suivante supprimera toutes les données de toutes les tables et remettra les compteurs d'incrémentation automatique à 1.
./manage.py sqlflush | psql DATABASE_NAME