我如何在Django中临时禁用数据库完整性约束-Postgresql

时间:2018-10-11 19:12:23

标签: django postgresql

我正在编写Django命令以播种现有表,

我需要在播种之前截断该表,但是该表上有外键约束。

因此,我在截表时出现 django.db.utils.IntegrityError

如何在Django中暂时关闭外键检查?

我看到了SET FOREIGN KEY CHECK = 0,但不知道将它们放在哪里:(

Django Command类:

class Command(BaseCommand):
help = "Command to seed the aws regions"
regions = [
    {
        'name': 'Us East (N. Virginia)',
        'region': 'us-east-1',
    },
    {
        'name': 'US West (Oregon)',
        'region': 'us-west-2',
    },
    {
        'name': 'EU (Ireland)',
        'region': 'eu-west-1',
    },
]
def handle(self, *args, **options):
    self.stdout.write('seeding regions...')

    AwsRegions.objects.all().delete() # this is where i get errors

    for name, region in self.regions:
        self.stdout.write(region)
        AwsRegions.objects.create(name, region)


    self.stdout.write('done seeding regions')

2 个答案:

答案 0 :(得分:0)

找到解决方案。

我必须禁用表上的Triggers才能停止外键约束检查。

禁用触发器

def disable_triggers(self):
        with connection.cursor() as cursor:
            cursor.execute('ALTER TABLE "Table Name" DISABLE TRIGGER ALL;')

启用触发器

def enable_triggers(self):
    with connection.cursor() as cursor:
        cursor.execute('ALTER TABLE "Table Name" ENABLE TRIGGER ALL;')

重要说明

  • 根据this doc link,您可以将列表作为第二个参数传递给execute()方法(例如:您可能希望动态传递表名),但这将自动转义这些变量,您可能最终形成语法错误的PostgreSQL查询(这花费了我很多时间来解决它)

  • 确保您重新正确打开触发器

  • 如果出现 权限被拒绝的错误 ,那么您可能要检查数据库用户权限,我刚刚从PgAdmin中打开了超级用户权限,这对我来说是可以的。一切恢复正常。 How to do it ?

答案 1 :(得分:0)

要禁用所有表的触发器(在需要将其停止用于多个表时有用):

SET session_replication_role TO 'replica'

要恢复:

SET session_replication_role TO 'origin'