【问题标题】:Can primary key use BigInteger as the AutoField in Django 1.2.4?主键可以使用 BigInteger 作为 Django 1.2.4 中的 AutoField 吗?
【发布时间】:2011-06-17 15:42:05
【问题描述】:

好像默认的主键是int。无论如何使用自动字段的大整数作为主键?

【问题讨论】:

标签: python django


【解决方案1】:

我建议你使用更新的 Django。官方的 Django 文档现在不超过 1.3。并且 1.3 不安全且不受支持。我知道这个问题是 3 年前提出的,但由于仍然没有公认的答案,我会试一试。

在 Django 1.6.5 中,您可以在模型中执行此操作:

class MyModel(models.Model):
    id = models.BigIntegerField(unique=True, primary_key=True)

primary_key=True 将覆盖模型上的默认 ID。在使用中,此字段会随着每个新模型对象自动递增。它只是工作!

【讨论】:

    【解决方案2】:

    我可以看到有几种方法可以实现这一点。无论哪种方式,您都必须定义您的 pk 字段。

    首先,只需创建自己的 id 字段并覆盖 save 方法。

    modelname(models.Model):
        # model definition
    
    def save(self):
        self.pkfield = nextIntFucntion()
        super(modelname, self).save()
    

    nextIntFunction() 很简单,查询按 id 排序的对象,然后得到 id+1

    我也找到了这个链接BigIntegerField and BigAutoField,貌似可以解决问题,但是我自己没有测试过

    【讨论】:

    • South 将正确迁移。如果您手动将数据输入数据库(或 django 外部),它将无法工作
    • nextIntFunction() 很简单,查询按 id 排序的对象,然后获取 id+1...如果多个阅读器同时将其加一,如何保证唯一性时间?
    • 嗯,好问题。由于 nextInt 将在保存时计算,所以机会非常渺茫......但仍然存在。这个想法的扩展,你可以保留一个“BigIntReference”表......
    • ...或者 Django 在保存时强制执行锁定...不确定。需要更多的研究来澄清
    • Django 在保存时不会强制锁定(至少在 1.6 中不会)。这是一个等待失败的竞争条件。更不用说如果你有足够的这个模型需要一个 bigint 键,你可能会很快保存它们,这只会增加达到这种条件的可能性。另一方面,由于它是主键,完整性将由数据库强制执行,因此您可以将超级调用置于循环中。
    【解决方案3】:

    我也遇到了同样的问题。 我添加了一些代码,例如

    User._meta.has_auto_field = True
    User._meta.auto_field = id
    

    我将 id 字段定义为 BigIntegerField(primary_key=True) 使用 user.Save() 后,user.id 就会有它的 id,不需要我再查询。 我认为它有效,但它不是一个漂亮的解决方案,所以我仍然在寻找一个好方法。

    【讨论】:

      【解决方案4】:

      由于Django 1.10,您可以按照documentation 中的说明使用BigAutoField,其工作方式与AutoField 完全相同,但它保证适合从1 到9223372036854775807 的数字。

      所以你可以像这样使用它:

      class SomeModel(models.Model):
          id = models.BigAutoField()
          ...
      

      【讨论】:

        【解决方案5】:

        您可以破解 Django 并将默认自动键更改为正确的值。签出:

        http://code.djangoproject.com/browser/django/trunk/django/db/backends/mysql/creation.py

        from django.conf import settings
        from django.db.backends.creation import BaseDatabaseCreation
        
        class DatabaseCreation(BaseDatabaseCreation):
            # This dictionary maps Field objects to their associated MySQL column
            # types, as strings. Column-type strings can contain format strings; they'll
            # be interpolated against the values of Field.__dict__ before being output.
            # If a column type is set to None, it won't be included in the output.
            data_types = {
                'AutoField':         'integer AUTO_INCREMENT',
                'BooleanField':      'bool',
                'CharField':         'varchar(%(max_length)s)',
        

        您可以在自己的代码中使用补丁来修改它:

        DatabaseCreation.data_types['AutoField'] = 'bigint AUTO_INCREMENT'
        

        您还必须修补 AutoField 类:

        http://code.djangoproject.com/browser/django/trunk/django/db/models/fields/__init__.py
        

        (未经测试的代码,祝你好运)

        【讨论】:

        • 破解框架绝不是一个好主意。扩展它总是更好。
        • 同样可以通过创建一个 AutoBigIntField 的子类 Model 来使用它作为它的默认 pk 并在后端使用适当的数据类型注册它。
        【解决方案6】:

        http://docs.djangoproject.com/en/dev/topics/db/models/

        类 BigIntegerField([**options])

        可用的选项是:

        主键 如果为 True,则该字段是模型的主键。

        毕竟你做了南迁: ALTER TABLE mytable 修改列 myid BIGINT(20) NOT NULL AUTO_INCREMENT;

        【讨论】:

        • 你确定是自动递增吗??
        【解决方案7】:

        你是对的,对不起。必要的sn-p在这里:

        http://djangosnippets.org/snippets/1244/

        允许使用 django 的 AutoField 创建具有自动增量设置的 bigint (mysql)、bigserial (psql) 或 NUMBER(19) (oracle) 字段,从而确保在调用时在实例中更新 ID它的 'save()' 方法。

        如果您只将 IntegerField 子类化为 BigIntegerField 并将其用作主键,则您创建的模型实例在调用“save()”时将不会获​​得 id 属性集,而是必须查询并加载实例再次从数据库中获取 ID。

        【讨论】:

          【解决方案8】:

          These snippets 工作。使用 BigAutoField 类作为模型的主键,它可以无缝运行,无需任何黑客攻击。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-02-10
            • 2013-07-12
            • 1970-01-01
            • 2020-05-24
            • 2020-04-13
            • 1970-01-01
            • 2018-07-14
            • 2021-09-06
            相关资源
            最近更新 更多