MySQL自增字段AUTO_INCREMENT值修改方法及Django常见错误排查

Ruby
Ruby
发布时间:2026-10-13| 6人浏览过
原创

本文详细讲解如何在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属性文档链接。希望能给大家一个参考,也希望大家多多支持本站。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。