使用SQLAlchemy和MS SQL Server实现唯一的if Null约束

时间:2016-04-20 15:06:52

标签: python sql-server sqlalchemy

我想对列强制执行唯一约束,但前提是它不为null。这是SQLite中的默认行为,但不是MS SQL Server中的默认行为。

在SQL Server中实现此目的的方法似乎是使用带有where子句的索引,如this post中所述。我的问题是我如何在SQLAlchemy中做到这一点,并让它仍然适用于SQLite。

我认为这大概就是我想要的:

class MyClass(Base):
    __tablename__ = 'myclass'
    __table_args__ = (Index('unique_index', <where clause?>, unique=True)
    my_column = Column(Integer) # The column I want unique if not null

其中<where clause?>是一个表达式,它将索引放在my_column上,而不是NULL。这似乎可以通过读取documentation索引来实现,但我不知道我需要什么表达式。非常感谢帮助这个或不同的方法。

2 个答案:

答案 0 :(得分:0)

使用过滤索引的

SQL Server解决方案:

CREATE TABLE tab(col INT);
CREATE UNIQUE INDEX uq_tab_col ON tab(col) WHERE col IS NOT NULL;

INSERT INTO tab(col) VALUES (1),(2),(NULL),(NULL);

-- INSERT INTO tab(col) VALUES (1);
-- Cannot insert duplicate key row in object 'dbo.tab' with unique index 'uq_tab_col'.
-- The duplicate key value is (1).

SELECT * FROM tab;

LiveDemo

答案 1 :(得分:0)

对于以后找到它的其他任何人。 SQL Alchemy现在确实支持此index documentation

import sqlalchemy as sa

sa.Table(
    sa.Column('column', sa.String(50), nullable=True),
    sa.Index('uq_column_allows_nulls', mssql_where=sa.text('column IS NOT NULL'),
)

如果您打算像我曾经使用此代码那样使用Alembic。

import sqlalchemy as sa
import alembic as op

op.create_index(
    name='uq_column_name',
    table_name='table',
    columns=['column'],
    mssql_where=sa.text('column IS NOT NULL'),
)

这将sql expression文本用于sqlalchemy和create_index的{​​{3}} mssql_where=