Django 迁移。如何检查迁移中是否存在表?

Gri*_*kin 5 python django postgresql

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

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

IF EXISTS (
    SELECT relname FROM pg_class WHERE relname=tablename
) THEN 
    DELETE FROM tablename END IF;
Run Code Online (Sandbox Code Playgroud)

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

django.db.utils.ProgrammingError: syntax error at or near "IF" 
Run Code Online (Sandbox Code Playgroud)

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

mrt*_*rts 7

检查表是否存在的最简单方法是使用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
Run Code Online (Sandbox Code Playgroud)


Gri*_*kin 1

使用 解决了它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
    ]
Run Code Online (Sandbox Code Playgroud)