如何在Django中支持AutoField(primary_key = False)? [英] How can I support AutoField(primary_key=False) in django?

查看:370
本文介绍了如何在Django中支持AutoField(primary_key = False)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要添加不是 主键的autoinc字段。我正在将使用自动递增字段的大型生产数据库迁移到 models.UUIDField 。我一直在进行逐段迁移,现在我的所有关系都重复了两种字段类型。我已经准备好进行主键交换,但是不幸的是,随着旧客户端的使用,我仍然需要保留自动递增整数字段。



由于django不允许我使用 primary_key = False 定义一个自动字段(即使在db层),我正在寻找一个简单的解决方案。我的最初策略是将字段更改为 models.BigIntegerField('GUID',db_index = True,null = True,unique = True),然后手动设置默认值 nextval('my_guid_seq':: regclass)使用 migrations.RunSQL 。到目前为止一切都很好,除非没有。事实证明,由于我的 null = True 声明,ORM层的django正在接管并插入 null ,其中将不允许数据库层的默认值来完成它的工作。



由于最糟糕的设计,核心开发人员很快就拒绝了这个请求,我最明确地同意这一点,但是有非常有效的用例。 https://code.djangoproject.com/ticket/8576



我是一个非常弱的django开发人员,所以我不想在ORM层进行杂草元编程。从定义上讲,这是一种hack,因此,我正在寻找最复杂,最有创意的解决方案,使我摆脱此限制

解决方案

您可以子类化 AutoField 并覆盖 _check_primary_key 方法。



<$从django.db.models.fields导入p $ p> 从django.db.models.fields导入AutoField
导入检查


类AutoFieldNonPrimary(AutoField ):

def _check_primary_key(self):
if self.primary_key:
return [
check.Error(
AutoFieldNonPrimary不得设置primary_key = True。,
obj = self,
id = fields.E100,

]
其他:
return []

请参见 AutoField 源代码此处



编辑:更新的链接


I need to add an autoinc field that is not the primary key. I am in the process of migrating a very large production database that uses autoincrementing fields to models.UUIDField. I have been doing a piecewise migration, and all of my relationships are now duplicated with both field types. I'm ready to make the primary key swap, but unfortunately I still need to keep the auto incrementing integer field for old clients as it becomes deprecated.

Since django will not allow me to define an autofield with primary_key=False (even though this is fully supported at the db layer), i'm looking for a simple solution. My initial strategy would be to simply change the field to models.BigIntegerField('GUID', db_index=True, null=True, unique=True) and then manually set the default nextval('my_guid_seq'::regclass) using migrations.RunSQL. So far so good, except not. It turns out, because of my null=True declaration, django at the ORM layer is taking over and inserting null which will not allow defaults at the database layer to do it's job.

The core developers are fast to reject this request because of bad design, which I most definetly agree with, but there are very valid use cases such as this. https://code.djangoproject.com/ticket/8576

I am a very weak django developer so I don't want to get in the weeds metaprogramming at the ORM layer. This is by definition a hack, so i'm looking for the least complex, creative solution that gets me around this limitation

解决方案

You could subclass AutoField and override the _check_primary_key method.

from django.db.models.fields import AutoField
from django.db.models.fields import checks


class AutoFieldNonPrimary(AutoField):

    def _check_primary_key(self):
        if self.primary_key:
            return [
                checks.Error(
                    "AutoFieldNonPrimary must not set primary_key=True.",
                    obj=self,
                    id="fields.E100",
                )
            ]
        else:
            return []

See AutoField source code here

Edit: Updated Link

这篇关于如何在Django中支持AutoField(primary_key = False)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆