【问题标题】:Create a DB index if it doesn't exist如果数据库索引不存在,则创建它
【发布时间】:2017-10-15 02:36:16
【问题描述】:

我有一个 Alembic 迁移,它创建了一些数据库中缺少的数据库索引。示例:

op.create_index(op.f('ix_some_index'), 'table_1', ['column_1'], unique=False)

但是,在其他已经有索引的环境中迁移失败:

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) relation "ix_some_index" already exists

对于这种情况,PostgreSQL 支持 IF NOT EXISTS 选项,但我看不到任何使用 Alembic 或 SQLAlchemy 选项调用它的方法。是否有检查现有索引的规范方法?

【问题讨论】:

    标签: postgresql sqlalchemy alembic


    【解决方案1】:

    这是一个适用于 PostgreSQL 的有点生硬的解决方案。它只是在创建新索引之前检查是否存在同名的索引。

    请注意,它不会验证索引是否位于正确的 Postgres 命名空间或任何其他可能相关的信息中。它适用于我的情况,因为我知道没有其他名称冲突的机会:

    def index_exists(name):
        connection = op.get_bind()
        result = connection.execute(
            "SELECT exists(SELECT 1 from pg_indexes where indexname = '{}') as ix_exists;"
                .format(name)
        ).first()
        return result.ix_exists
    
    def upgrade():
        if not index_exists('ix_some_index'):
            op.create_index(op.f('ix_some_index'), 'table_1', ['column_1'], unique=False)
    

    【讨论】:

    • 使用pg_indexes 而不是pg_class 会更好(这也将使检查正确的模式和表更容易)。使用pg_class时,最好使用relkind = 'i'而不是reltype = 0
    • @a_horse_with_no_name 谢谢,我已更新代码以使用pg_indexes
    • @DagHøidahl 感谢这个..CI CD 管道上长时间运行的语句正在超时我们的 ECS 容器,这很有帮助
    猜你喜欢
    • 1970-01-01
    • 2021-05-02
    • 2013-09-08
    • 2013-04-23
    • 2017-03-13
    • 2023-02-06
    • 1970-01-01
    • 1970-01-01
    • 2018-12-04
    相关资源
    最近更新 更多