如何使用 SQLAlchemy 和 alembic 声明 NOT VALID PostgreSQL 约束?

How to declare NOT VALID PostgreSQL constraints with SQLAlchemy and alembic?

我想创建一个标记为 NOT VALID 的 PostgreSQL CHECK 约束,但我没有看到在 alembic 中创建此类约束或声明的方法它使用 SQLAlchemy。

看起来 SQLAlchemy 添加了对 NOT VALID 约束自省的支持,但不是相反:https://github.com/sqlalchemy/sqlalchemy/commit/3980a9a455d08c5073cabc3c2b77de46fa36d7b4 .

有办法吗?还是只是缺少该功能,我需要用 alembic 手动编写 SQL 语句?

SQLAlchemy 1.4.32 中添加了对在 PostgreSQL 方言中声明 NOT VALID 约束的支持。可以通过将 postgresql_not_valid 方言选项设置为 True:

来声明此类约束
import sqlalchemy as sa


sa.CheckConstraint(
    "lastname IS NOT NULL",
    postgresql_not_valid=True,  # ⬅
)
sa.ForeignKeyConstraint(
    ["head_teacher_id"],
    ["teachers.id"],
    postgresql_not_valid=True,  # ⬅
)

Alembic 的 create_check_constraint and create_foreign_key 函数会将任何方言选项转发给 SQLAlchemy,因此创建具有此类约束的迁移非常简单:

from alembic import op


def upgrade():
    op.create_check_constraint(
        "ck_lastname_not_null",
        "students",
        "lastname IS NOT NULL",
        postgresql_not_valid=True,  # ⬅
    )
    op.create_foreign_key(
        "fk_head_teacher",
        "students",
        "teachers",
        ["head_teacher_id"],
        ["id"],
        postgresql_not_valid=True,  # ⬅
    )


def downgrade():
    op.drop_constraint("ck_lastname_not_null", "students")
    op.drop_constraint("fk_head_teacher", "students")

另请参阅 PostgreSQL constraint options 文档。