You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django3.2如何创建PostgreSQL基于函数的唯一索引

问题原因

你之前把 TruncDate 表达式放到了 UniqueConstraint 的 fields 参数里,fields 参数仅支持传入字符串格式的模型字段名,不支持数据库函数/表达式,所以会报字段不存在的错误。

正确实现方案

Django 3.2 中 UniqueConstraint 支持 expressions 参数专门用于实现基于函数/表达式的唯一约束,配置如下:
首先导入依赖:

import datetime
from django.db import models
from django.db.models import UniqueConstraint, TruncDate

修改模型的Meta配置:

class UserCheckin(GeneralModel):
    id = models.BigAutoField(primary_key=True)
    user_id = models.BigIntegerField()
    create_time = models.DateTimeField()
    
    class Meta:
        constraints = [
            UniqueConstraint(
                expressions=[
                    "user_id",
                    # 指定UTC时区,保证和原生SQL逻辑完全一致
                    TruncDate("create_time", tzinfo=datetime.timezone.utc)
                ],
                name="user_date_checkin",
                # 可选:如果需要添加过滤条件,加condition参数即可
                # condition=models.Q(user_id__isnull=False)
            )
        ]

执行迁移后生成的SQL和你手写的原生SQL完全一致:

create unique index user_date_checkin
on usercheckin (user_id, (timezone('UTC'::text, create_time)::date));

备选方案

如果有特殊场景ORM无法满足,也可以手动创建迁移文件,通过RunSQL执行原生SQL语句:

from django.db import migrations

class Migration(migrations.Migration):
    dependencies = [
        ("your_app_name", "000x_previous_migration_number"),
    ]
    operations = [
        migrations.RunSQL(
            sql="""
            create unique index user_date_checkin
            on usercheckin (user_id, (timezone('UTC'::text, create_time)::date));
            """,
            reverse_sql="drop index user_date_checkin;"
        )
    ]

内容的提问来源于stack exchange,提问作者jiamo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 23:24:03