我一直在研究我的Django网络应用程序的离线版本,并经常删除某个ModelX的模型实例。
我是从管理页面完成此操作并且没有遇到任何问题。该模型只有两个字段:名称和顺序,与其他模型没有其他关系。
新实例被赋予下一个可用的pk,当我删除所有实例时,添加一个新实例会产生pk = 1,这是我期望的。
将代码在线移动到我的实际数据库我注意到情况并非如此。我需要更改模型实例,所以我将它们全部删除了,但令我惊讶的是主键不断增加而不重置为1.
使用我检查过的Django API进入数据库并且旧的实例已经消失,但是即使添加新实例也会产生一个主键,它会在最后一个被删除的实例停止的地方找到,而不是1。
想知道是否有人知道这里可能存在什么问题。
答案 0 :(得分:20)
我不会称之为问题。这是许多数据库系统的默认行为。基本上,表的自动递增计数器是持久的,删除条目不会影响计数器。主键的实际价值不会影响性能或任何东西,它只具有审美价值(如果你达到了20亿的限制,你很可能会担心其他问题)。
如果您确实要重置计数器,可以删除并重新创建表格:
python manage.py sqlclear <app_name> > python manage.py dbshell
或者,如果您需要保留应用程序中其他表的数据,您可以手动重置计数器:
python manage.py dbshell
mysql> ALTER TABLE <table_name> AUTO_INCREMENT = 1;
您在离线和在线应用中看到不同行为的最可能原因是自动增量值仅存储在内存中,而不是存储在磁盘上。每次重新启动数据库服务器时,它都会重新计算为MAX(<column>) + 1
。如果表为空,则在重新启动时将完全重置。这可能经常用于您的离线环境,并且对于您的在线环境几乎为零。
答案 1 :(得分:16)
正如其他人所说,这完全是数据库的责任。
但你应该意识到这是理想的行为。 ID唯一标识数据库中的实体。因此,它应该只引用一行。如果随后删除了该行,则没有理由要求新行重新使用该ID:如果您这样做,则会在以前删除的实体之间造成混淆拥有该ID,以及新创建的ID重用它。这样做没有意义,你不应该这样做。
答案 2 :(得分:3)
您是否实际从数据库中删除它们或者是否使用Django删除它们? Django不会仅仅通过从中删除行来更改表的AUTO_INCREMENT
,因此如果要重置主键,则可能需要进入数据库并执行以下操作:
ALTER TABLE <my-table> AUTO_INCREMENT = 1;
(这假设你使用的是MySQL或类似的东西)。
答案 3 :(得分:3)
没有问题,这就是数据库的工作方式。 Django与生成id没有任何关系,它只是告诉数据库插入一行并从数据库中获取响应中的id。每个表的id从1开始,每次插入一行时都会递增。删除行不会导致id返回。您通常不应该关注这一点,您需要知道的是每一行都有一个唯一的ID 您当然可以使用数据库命令更改为您的表生成id的计数器,这取决于您正在使用的特定数据库系统。
答案 4 :(得分:2)
如果您使用的是SQLite,可以使用以下shell命令重置主键:
DELETE FROM your_table; DELETE FROM SQLite_sequence WHERE name =&#39; your_table&#39;;
答案 5 :(得分:0)
我不确定何时添加,但以下管理命令将删除所有表中的所有数据,并将自动增量计数器重置为1.
a(b(cd))
答案 6 :(得分:0)
针对“ POSTGRES”数据库的另一种解决方案是从用户界面。 选择表格并查找“序列”下拉列表,然后选择设置并以这种方式调整序列。
示例: