【问题标题】:Django reached maximum value of sequenceDjango达到序列的最大值
【发布时间】:2025-06-14 07:00:01
【问题描述】:

我正在运行一个每天创建数百万条记录的程序,在运行该程序一年多之后,我的 postgres 数据库似乎已达到 id 限制。

我收到的错误是

django.db.utils.DataError: nextval: 达到序列“main_records_id_seq”的最大值 (2147483647)

有没有办法使用 SQL 或 django ORM 来扩展最大 id?还是有更好的解决方案?

【问题讨论】:

    标签: django postgresql django-orm


    【解决方案1】:

    Django 默认使用AutoField [Django-doc] 来指定数据库端主键的值。 AutoFieldIntegerField [Django-doc],正如 Django 文档所说:

    一个整数。 -21474836482147483647 的值在 Django 支持的所有数据库中都是安全的。

    您可以改用BigAutoField [Django-doc],它将使用:

    一个 64 位整数,很像 AutoField,只是它保证适合从 19223372036854775807 的数字

    如果您的应用程序在一年内生成 2'147'483'647,您可以使用 BigAutoField 4'294'967'298 年。

    因此,您可以将模型定义为:

    class MyModel(models.Model):
        id = models.BigAutoField(primary_key=True)

    【讨论】:

    • Django 会自动处理迁移吗?
    • 我现在正在运行迁移,它需要一段时间,因为它正在应用于大量记录,但看起来它正在工作。如果它完成或收到错误,我会报告。
    • @HoratiuJeflea:如果我将 id 字段添加到测试项目的模型中,它确实会进行迁移,对于 PostgreSQL,它会更改字段(使用 sqlmigrate 你可以检查查询)。
    • @HoratiuJeflea 迁移由 Django 自动处理,实际上应用得非常快。
    【解决方案2】:

    这仅与 PostgreSql 相关,与 Django ORM 无关。不幸的是,该解决方案并非微不足道,this 是一篇很好的文章,介绍了 DB id 迁移的 4 种策略,各有利弊。

    策略总结:

    1. 使用 ALTER COLUMN 更改数据类型。
    2. 创建一个具有相同架构但 ID 类型为 bigint 的新表,并使用 INSERT INTO。
    3. 此策略与策略 2 非常相似,不同之处在于我们不是在一个 SQL 查询中复制数据,而是慢慢复制数据块 更长时间的记录。
    4. 向表中添加一个 bigint 类型的新列。将 id 值复制到 id_bigint,然后将新列重命名为 id(通过 将现有 id 重命名为 id_old)。

    【讨论】:

      最近更新 更多