Klucze podstawowe instancji modelu Django nie resetują się do 1 po usunięciu wszystkich instancji

Pracowałem nad wersją offline mojej aplikacji internetowej Django i często usuwałem instancje modelu dla określonego ModelX.

Zrobiłem to ze strony admina i nie doświadczyłem żadnych problemów. Model ma tylko dwa pola: Nazwa i kolejność i nie ma innych relacji z innymi modelami.

Nowe instancje otrzymują następne dostępne pk, co ma sens, a kiedy usunąłem wszystkie instancje, dodanie nowej instancji daje pk=1, czego oczekuję.

Przenoszenie kod online do mojej rzeczywistej bazy danych zauważyłem, że tak nie jest. Musiałem zmienić instancje modelu, więc usunąłem je wszystkie, ale ku mojemu zaskoczeniu klucze podstawowe utrzymywały się na inkrementacji bez resetowania z powrotem do 1.

Wchodzenie do bazy danych za pomocą API Django sprawdziłem i stare instancje zniknęły, ale nawet dodawanie nowych instancji daje klucz podstawowy, który pobiera miejsce, w którym ostatnia usunięta instancja została przerwana, zamiast 1.

Zastanawiam się, czy ktoś wie, co może być problem tutaj.

Author: pj2452, 2015-01-02

6 answers

Jak stwierdzili inni, jest to całkowicie odpowiedzialność bazy danych.

Ale powinieneś zdać sobie sprawę, że jest topożądane zachowanie. Identyfikator jednoznacznie identyfikuje podmiot w Twojej bazie danych. Jako taki powinien odnosić się tylko do jednego wiersza. Jeśli ten wiersz zostanie następnie usunięty, nie ma powodu, dla którego nowy wiersz powinien ponownie użyć tego identyfikatora: jeśli to zrobisz, spowoduje to zamieszanie między usuniętym elementem, który miał ten identyfikator, a nowo utworzonym to go ponownie wykorzystało. Nie ma sensu tego robić i nie powinieneś tego chcieć.

 14
Author: Daniel Roseman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-01 23:01:41

Nie nazwałbym tego problemem. Jest to domyślne zachowanie dla wielu systemów bazodanowych. Zasadniczo licznik auto-inkrementacji tabeli jest trwały, a usuwanie wpisów nie wpływa na licznik. Rzeczywista wartość klucza podstawowego nie ma wpływu na wydajność ani nic, ma tylko wartość estetyczną (jeśli kiedykolwiek osiągniesz limit 2 miliardów, najprawdopodobniej będziesz miał inne problemy do zmartwienia).

Jeśli naprawdę chcesz zresetować licznik, możesz upuścić i odtworzyć Tabela:

python manage.py sqlclear <app_name> > python manage.py dbshell

Lub, jeśli chcesz zachować dane z innych tabel w aplikacji, możesz ręcznie zresetować licznik:

python manage.py dbshell
mysql> ALTER TABLE <table_name> AUTO_INCREMENT = 1;

Najbardziej prawdopodobnym powodem, dla którego widzisz różne zachowania w aplikacjach offline i online, jest to, że wartość auto-increment jest przechowywana tylko w pamięci, a nie na dysku. Jest on przeliczany jako MAX(<column>) + 1 za każdym razem, gdy serwer bazy danych jest restartowany. Jeśli tabela jest pusta, zostanie całkowicie zresetowana przy ponownym uruchomieniu. Jest to prawdopodobnie bardzo często dla środowiska offline, a prawie żaden Dla środowiska online.

 18
Author: knbk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-01 23:38:54

Czy rzeczywiście upuściłeś je ze swojej bazy danych, czy usunąłeś je używając Django? Django nie zmieni AUTO_INCREMENT dla Twojej tabeli po prostu usuwając z niej wiersze, więc jeśli chcesz zresetować swoje klucze główne, być może będziesz musiał wejść do swojego db i:

ALTER TABLE <my-table> AUTO_INCREMENT = 1;

(zakłada się, że używasz MySQL lub podobnego).

 3
Author: xnx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-01 22:52:09

Nie ma problemu, tak działają bazy danych. Django nie ma nic wspólnego z generowaniem id, po prostu mówi bazie danych, aby wstawiła wiersz i pobiera id w odpowiedzi z bazy danych. Identyfikator rozpoczyna się od 1 dla każdej tabeli i zwiększa się za każdym razem, gdy wstawiasz wiersz. Usunięcie wierszy nie powoduje powrotu identyfikatora. Zazwyczaj nie powinieneś się tym martwić, wszystko, co musisz wiedzieć, to to, że każdy wiersz ma unikalny identyfikator.
Możesz oczywiście zmienić licznik, który generuje id dla Twojego tabela z poleceniem bazy danych i to zależy od konkretnego systemu bazodanowego, którego używasz.

 3
Author: nima,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-01 22:54:38

Jeśli używasz SQLite możesz zresetować klucz główny za pomocą następujących komend Powłoki:

DELETE FROM your_table; DELETE FROM SQLITE_SEQUENCE WHERE name= 'your_table';

 2
Author: Juan Navarrete,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-19 15:15:16

Nie jestem pewien, kiedy to zostało dodane, ale następujące polecenie zarządzania usunie wszystkie dane ze wszystkich tabel i zresetuje liczniki automatycznego przyrostu do 1.

./manage.py sqlflush | psql DATABASE_NAME
 0
Author: Dan Loewenherz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-02 00:59:43