MySQL自增字段AUTO_INCREMENT值修改方法及Django常见错误排查
本文详细讲解如何在MySQL中查看并修改自增字段AUTO_INCREMENT的起始值,通过建表、插入数据及清空记录的操作演示其机制。同时补充Django开发中常见的AttributeError及abstract属性配置错误,提供具体的代码修正方案,帮助开发者避开这些常见坑点。
MySQL自增字段AUTO_INCREMENT值修改方法
在之前的文章中我们提到,如果使用DELETE语句删除数据库表中的记录,仅仅会移除数据行,而自增ID的值会保持在上次使用的状态。
也就是说,如果删除前存在四条数据,删除后再插入新数据,ID将从5开始递增。
但如果我们明确希望新插入数据的ID从2开始,该如何操作呢?
这时我们需要了解如何修改数据表的特定属性,即AUTO_INCREMENT。
首先,我们需要掌握查看该属性值的方法。
例如,我们创建了一张测试表:
create table t4(id int auto_increment primary key, num int) engine=innodb default charset=utf8;
接下来,我们可以通过特定命令来查看AUTO_INCREMENT的当前值:

通过上述命令,我们可能并未直接看到AUTO_INCREMENT属性,这是为什么呢?原因在于刚创建的表尚未插入数据,因此该属性尚未被初始化赋值。
为此,我们先插入几条测试数据:
insert into t4(num) values(11);
insert into t4(num) values(12);
insert into t4(num) values(13);
执行上述SQL语句插入三条记录。
在此处我们可以推测,AUTO_INCREMENT属性的值究竟代表什么?是记录最后一条数据的ID,还是指示下一条记录的ID?
我们可以再次通过命令 show create table t4 \G; 来验证这一猜想。

此时,我们可以找到AUTO_INCREMENT属性,其值为4。这是否说明AUTO_INCREMENT记录的值实际上是指向下一条记录的ID?
接着,使用 delete from t4; 命令清空t4表中的所有记录。
然后再次调用 show create table t4 \G; 命令查看表结构。

可以发现,尽管表内数据已被删除,但表元数据中的信息并未重置。这样一来,如果我们希望新添加的数据ID从2开始,似乎就无法直接实现了?
但是,我们可以通过修改表结构来解决这个问题。
执行命令 alter table t4 AUTO_INCREMENT=2; 即可将AUTO_INCREMENT属性的值修改为2。这样,后续添加的数据ID就会从2开始递增。
最后,我们再次验证修改结果。

结果显示符合预期,问题完美解决。
Django Model常见错误排查与解决
补充知识:Django中Model常见错误之AttributeError: type object ** has no attribute 'objects'及Field defines a relation
Django中Model常见错误之AttributeError: type object ** has no attribute 'objects'及Field defines a relation with model **, which is either not installed, or is abstract.
1. AttributeError: type object ** has no attribute ‘objects'
作者目前使用的是Django 1.8.1版本。在一次新项目启动中,编译查询代码时(如下所示),总是抛出上述错误。有人建议自己在Model中重新引入objects,即 objects = Model.manager(),然而问题并未得到解决。
queryset = CompanyAuthRecord.objects.all()
最终发现,将 abstract = True 注释掉即可完美解决该问题。至于当初为何添加这一属性,似乎是在引入此Model时总是引入失败,据他人建议加入此属性即可。事实确实解决了那个引入问题,但当初并未深究原因,应了那句话:欠下的,迟早要还!
class CompanyAuthRecord(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, db_column='c_id')
company_seal = models.OneToOneField(CompanySeal, verbose_name='企业印章id', null=True,
db_column='c_company_seal_id')
add_by_id = models.UUIDField(verbose_name='添加人id', db_column='c_add_by_id', null=True, default=None)
add_dt = models.DateTimeField('添加时间', db_column='c_add_dt', auto_now_add=True)
class Meta:
db_table = 't_company_auth_record'
verbose_name = '企业认证状态记录表'
# abstract = True
ordering = ["add_dt"]
default_permissions = ()
附关于abstract=True的官方解释:

2.Field defines a relation with model **, which is either not installed, or is abstract.
解决了上述问题后,又出现了新的错误。难道真要上演程序员修水管的景象?几经周折,原因出现在被关联Model的 app_label = 'seal' 属性上,如下注释即可解决问题。至于原因:Django的要求是,你可以不设置这个参数,但如果设置了,必须与你的App名称保持一致。而我正是犯了这样的错误。
class CompanySeal(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, db_column='c_id')
add_by_id = models.UUIDField(verbose_name=u'添加人id', db_column='c_add_by_id', null=True, default=None)
add_dt = models.DateTimeField(verbose_name=u'添加时间', db_column='c_add_dt', auto_now_add=True)
class Meta:
# app_label = 'seal'
db_table = 't_company_seal'
verbose_name = '企业电子印章数据表'
ordering = ["add_dt"]
default_permissions = ()
以上经验希望能帮助到遇到同样问题的你。问题本身并不复杂,只怪我们不够细心,多查阅文档和源码才是提升之道。附关于Meta属性文档链接。希望能给大家一个参考,也希望大家多多支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













