Подтвердить что ты не робот

Первичные ключи экземпляров модели Django не от reset до 1 после удаления всех экземпляров

Я работал над автономной версией своего веб-приложения Django и часто удалял экземпляры моделей для определенного ModelX.

Я сделал это со страницы администратора и не испытывал никаких проблем. Модель имеет только два поля: имя и порядок, а также другие отношения с другими моделями.

Новые экземпляры получают следующий доступный pk, который имеет смысл, и когда я удалю все экземпляры, добавление нового экземпляра дает pk = 1, который я ожидаю.

Перемещение кода онлайн в мою фактическую базу данных Я заметил, что это не так. Мне нужно было изменить экземпляры модели, поэтому я удалил их все, но, к моему удивлению, первичные ключи продолжали увеличиваться, не возвращаясь к 1.

Переход в базу данных с помощью Django API, который я проверил, и старые экземпляры исчезли, но даже добавление новых экземпляров дает первичный ключ, который выбирает, где остановился последний удаленный экземпляр, вместо 1.

Интересно, знает ли кто-нибудь, что может быть проблемой здесь.

4b9b3361

Ответ 1

Как заявили другие, это полностью зависит от базы данных.

Но вы должны понимать, что это желаемое поведение. Идентификатор уникально идентифицирует объект в вашей базе данных. Таким образом, он должен всегда ссылаться только на одну строку. Если эта строка впоследствии удалена, нет причин, по которым вам нужно, чтобы новая строка повторно использовала этот идентификатор: если вы это сделали, вы создадите путаницу между теперь удаленным объектом, который имел этот идентификатор, и недавно созданный, который повторно использовал его. Нет смысла делать это, и вы не должны этого делать.

Ответ 2

Я бы не назвал это проблемой. Это поведение по умолчанию для многих систем баз данных. В принципе, счетчик автоматического нарастания для таблицы является постоянным, а удаление записей не влияет на счетчик. Фактическое значение первичного ключа не влияет на производительность или что-то еще, оно имеет только эстетическую ценность (если вы когда-либо достигнете ограничения в 2 миллиарда, у вас, скорее всего, возникнут другие проблемы).

Если вы действительно хотите reset счетчика, вы можете отбросить и заново создать таблицу:

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

Или, если вам нужно сохранить данные из других таблиц в приложении, вы можете вручную reset счетчик:

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

Наиболее вероятная причина, по которой вы видите другое поведение в автономных и онлайн-приложениях, заключается в том, что значение автоматического прироста сохраняется только в памяти, а не на диске. Он пересчитывается как MAX(<column>) + 1 каждый раз, когда сервер базы данных перезапускается. Если таблица пуста, она будет полностью reset при перезапуске. Это, вероятно, очень часто для автономной среды и практически не подходит для вашей онлайн-среды.

Ответ 3

Вы фактически удалили их из своей базы данных или удалили их с помощью Django? Django не изменит AUTO_INCREMENT для вашей таблицы, просто удалив из нее строки, поэтому, если вы хотите reset ваши первичные ключи, вам может понадобиться войти в ваш db и:

ALTER TABLE <my-table> AUTO_INCREMENT = 1;

(Предполагается, что вы используете MySQL или аналогичный).

Ответ 4

Нет проблем, так как работают базы данных. Django не имеет ничего общего с созданием идентификаторов, он просто сообщает базе данных вставить строку и получает идентификатор в ответ от базы данных. Идентификатор начинается с 1 для каждой таблицы и увеличивается каждый раз, когда вы вставляете строку. Удаление строк не приводит к возврату идентификатора. Обычно вы не должны беспокоиться об этом, все, что вам нужно знать, это то, что каждая строка имеет уникальный идентификатор.
Вы можете, конечно, изменить счетчик, который генерирует идентификатор для вашей таблицы с помощью команды базы данных и зависит от конкретной системы баз данных, которую вы используете.

Ответ 5

Если вы используете SQLite, вы можете reset первичный ключ со следующими командами оболочки:

УДАЛИТЬ ИЗ your_table; УДАЛИТЬ ИЗ SQLite_sequence WHERE name= 'your_table';

Ответ 6

Я не уверен, когда это было добавлено, но следующая команда управления удалит все данные из всех таблиц и будет reset счетчики автоматического увеличения в 1.

./manage.py sqlflush | psql DATABASE_NAME