【问题标题】:Django migrations. How to check if table exists in migrations?Django 迁移。如何检查迁移中是否存在表?
【发布时间】:2016-11-11 11:12:27
【问题描述】:

我目前正在开发基于 Django 1.8 和 Postgres 的应用程序。这个应用程序安装在几个环境中,其中一些环境中有数据库中的旧表,我需要从中删除记录。

我使用以下 SQL 查询编写了迁移:

IF EXISTS (
    SELECT relname FROM pg_class WHERE relname=tablename
) THEN 
    DELETE FROM tablename END IF;

但是 Django 在这个查询中抛出错误:

django.db.utils.ProgrammingError: syntax error at or near "IF" 

我可以在迁移中以某种方式检查该表是否存在,然后才执行查询,例如DROP FROM tablename ?

【问题讨论】:

    标签: python django postgresql


    【解决方案1】:

    检查表是否存在的最简单方法是使用django.db.connection.introspection.table_names():

    from django.db import connection
    
    ...
    
    all_tables = connection.introspection.table_names()
    old_tables = set('old_table_1', 'old_table_2')
    existing_old_tables = old_tables.union(all_tables)
    # clean tables in existing_old_tables with migrations.RunSQL() as suggested above
    

    【讨论】:

    • 当你在迁移之前有 Model.objects.query() 内联时,这个非常有用 ProgramingError 但是这被 django.db.connection.introspection.table_names() 阻止了,例如:Model.objects.query() if django.db.connection.introspection.table_names() else []
    【解决方案2】:

    使用django.db.connection 解决了这个问题。代码:

    from django.db import migrations
    from django.db import connection
    
    
    class Migration(migrations.Migration):
        db_cursor = connection.cursor()
        check_exists_query = "SELECT relname FROM pg_class WHERE relname=%s;"
        base_query = "DELETE FROM {table} WHERE condition;"
        tables = [tables]
        existing_tables = []
    
        for table in tables:
            db_cursor.execute(check_exists_query, [table])
            result = db_cursor.fetchone()
            if result:
                existing_tables.append(table)
    
        operations = [
            migrations.RunSQL(base_query.format(table=existing_table)) for existing_table in existing_tables
        ]
    

    【讨论】:

    • 这会清空你所有的桌子。那么问题来了,为什么不删除数据库呢?
    • 同意,这不是最有用的例子。使用WHERE 条件更新了删除查询
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-05
    • 2023-04-10
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 2015-07-03
    • 2018-10-10
    相关资源
    最近更新 更多