如何在django迁移中执行原始SQL

时间:2015-07-29 10:38:20

标签: django postgresql database-partitioning django-migrations

我知道Django中的游标对象。在迁移中是否还有其他首选方法可以执行原始SQL?我想为我的一个模型表引入postgresql分区。分区逻辑是一系列功能和触发器,必须在我想要自动化的设置中添加到数据库中。

2 个答案:

答案 0 :(得分:38)

单程:

我发现这样做的最好方法是使用RunSQL:

迁移包含RunSQL类。要做到这一点:

  1. ./manage.py makemigrations --empty myApp
  2. 编辑创建的迁移文件以包含:
  3. operations = [ migrations.RunSQL('RAW SQL CODE') ]

    正如纳撒尼尔·奈特所提到的,RunSQL也接受reverse_sql参数来反转迁移。 See the docs for details

    另一种方式

    我最初解决问题的方法是使用post_migrate信号来调用游标来执行我的原始SQL。

    我必须添加到我的应用中的是:

    在myApp的__init__.py中添加:

    default_app_config = 'myApp.apps.MyAppConfig'
    

    创建文件apps.py

    from django.apps import AppConfig
    from django.db.models.signals import post_migrate
    from myApp.db_partition_triggers import create_partition_triggers
    
    
    class MyAppConfig(AppConfig):
        name = 'myApp'
        verbose_name = "My App"
    
        def ready(self):
            post_migrate.connect(create_partition_triggers, sender=self)
    

    新文件db_partition_triggers.py

    from django.db import connection
    
    
    def create_partition_triggers(**kwargs):
        print '  (re)creating partition triggers for myApp...'
        trigger_sql = "CREATE OR REPLACE FUNCTION...; IF NOT EXISTS(...) CREATE TRIGGER..."
        cursor = connection.cursor()
        cursor.execute(trigger_sql)
        print '  Done creating partition triggers.'
    

    现在每个manage.py syncdbmanage.py migrate都会调用此函数。因此,请确保它使用CREATE OR REPLACEIF NOT EXISTS。所以它可以处理现有的功能。

答案 1 :(得分:0)

我建议 django-migrate-sql-deux https://pypi.org/project/django-migrate-sql-deux/

这样,您可以以声明方式(如Django中的模型)管理数据库对象,例如视图,函数,触发器。然后,您需要通过makemigrations对Django迁移进行更改。并通过migrate应用它们。因此,开发和部署流程非常相似。

如果Django拥有适用于原始SQL“模型”的系统并以{em> django-migrate-sql-deux之类的makemigrationsmigrate命令自动处理迁移和依赖关系,那就太棒了/ em>。