django - Django 创建唯一函数索引
问题描述
使用 postgresql 我们可以创建唯一的函数索引:
create unique index user_date_checkin
on unique_user_date (user_id, (timezone('UTC'::text, create_time)::date));
但是对于 Django 3.2:
class UserCheckin(GeneralModel):
id = models.BigAutoField(primary_key=True)
user_id = models.BigIntegerField()
create_time = models.DateTimeField()
class Meta:
indexes = [
models.Index("user_id", TruncDate("create_time"), name="user_date_checkin"),
]
只能得到这样的sql生成:
create index user_date_checkin
on test (user_id, (timezone('UTC'::text, create_time)::date));
和UniqueConstraint
constraints = [
models.UniqueConstraint(
fields=["user_id", TruncDate("create_time")],
name="user_date"),
]
refers to the nonexistent field 'TruncDate(F(create_time))
出错了
那么如何在 Django 3.2 中创建具有函数的唯一索引?
更新
在 django 源代码django/db/backends/base/schema.py
中,我发现:
if condition or include or opclasses:
sql = self.sql_create_unique_index
else:
sql = self.sql_create_unique
但在这种情况下我没有这样的条件或操作类
更新
添加条件后:
indexes = [
models.Index("user_id", TruncDate("create_time"),
condition=Q(user_id__isnull=False), name="user_date_checkin"),
]
还是不要在unique
这里添加:
-- auto-generated definition
create index user_date_checkin
on voip_usercheckin (user_id, (timezone('UTC'::text, create_time)::date))
where (user_id IS NOT NULL);
解决方案
Django 还不支持功能约束。但此功能已经在开发中,将成为 Django 4.0 版的一部分,预计将于 2021 年 12 月发布。现在您可以通过自定义迁移执行您的 sql:
首先运行您拥有模型的应用程序在哪里python manage.py makemigrations yourapp --empty
。yourapp
接下来编辑生成的迁移并添加RunSQL
[Django-docs]操作:
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
...
]
operations = [
migrations.RunSQL(
sql="create unique index user_date_checkin on unique_user_date (user_id, (timezone('UTC'::text, create_time)::date));",
reverse_sql="DROP INDEX IF EXISTS user_date_checkin;"
),
]
python manage.py migrate
在此之后,您可以通过运行将在数据库中创建索引来应用此迁移。
在 Django 4.0 发布后,您可能(可能会更改)编写以下内容:
constraints = [
models.UniqueConstraint(
"user_id",
TruncDate("create_time"),
name="user_date"),
]
推荐阅读
- python - 使用 xml-rpc (python) 版本 14 从销售订单创建发票
- javascript - 如何检查 innerHTML 是否为空?
- node.js - 如何访问其他文件中的 dotenv 变量
- google-apps-script - 条件逻辑和循环:我怎样才能让它正常工作?
- web-services - Jmeter:一个请求 - 两个或多个响应 - 如何正则表达式提取器?
- html - 悬停时如何使用 CSS 将角度字符添加到此按钮的文本中?
- php - php重定向会根据浏览器失败吗?
- javascript - MongoDB if 语句
- html - 自定义图像在移动视图上没有响应
- python - Python 的类型提示语法是否在不导入键入模块的情况下提供“任何”等价物?