【问题标题】:Alembic MSSQL Unique Constraint Allow NullsAlembic MSSQL 唯一约束允许空值
【发布时间】:2021-05-09 02:14:21
【问题描述】:

要解决的问题

使用 MSSQL,我想要一个唯一的列并接受空值。

问题

  1. 将两行数据添加到允许具有唯一约束的空值的列中,如下面的实现中给出了以下错误:

    Violation of UNIQUE KEY constraint 'UQ_...'. Cannot insert duplicate key in 
    object 'TABLE'. The duplicate key value is (<NULL>). (2627) (SQLExecDirectW)"
    
  2. 降级列会导致与reference 列相关的约束问题。约束会自动唯一命名,因此以编程方式删除很痛苦。

当前实施

alembic 操作是:

from alembic import op
import sqlalchemy as sa

#...

def upgrade():
    op.add_column(
        'TABLE', sa.Column('reference', sa.Integer(), nullable=True, unique=True),
    )


def downgrade():
    op.drop_column('TABLE', 'reference')

【问题讨论】:

  • 下面的答案不是这样吗?它在upgrade 函数中
  • 不用担心。我没有让答案足够清楚:)。我只是扩展了答案。希望这能让它更清楚一点

标签: sql-server python-3.x sqlalchemy alembic


【解决方案1】:

在唯一字段中允许空值的解决方案是:

  1. 定义列时不要创建唯一约束
op.add_column(
        'TABLE', sa.Column('reference', sa.Integer(), nullable=True), # No unique=True
    )
  1. 手动创建unique index
op.create_index(
    'uq_reference_allow_nulls', table_name='TABLE', columns=['reference'],
    mssql_where=sa.text('reference IS NOT NULL'), unique=True,
)
  1. 降级时删除索引。
op.drop_index('uq_reference_allow_nulls', table_name='TABLE')

这也解决了在表上有随机唯一约束的问题,因为unique 参数被删除了。总而言之,alembic 修订看起来像这样:

from alembic import op
import sqlalchemy as sa

#...

def upgrade():
    op.add_column(
        'TABLE', sa.Column('reference', sa.Integer(), nullable=True),  # Do not include unique here
    )
    op.create_index(
        'uq_reference_allow_nulls', table_name='TABLE', columns=['reference'],
        mssql_where=sa.text('reference IS NOT NULL'), unique=True,
    )


def downgrade():
    op.drop_index('uq_reference_allow_nulls', table_name='TABLE')
    op.drop_column('TABLE', 'reference')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-20
    • 2016-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多