如何在Django中支持AutoField(primary_key = False)? [英] How can I support AutoField(primary_key=False) in django?
问题描述
我需要添加不是 主键的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屋!