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

Posted

技术标签:

【中文标题】如何在 django 迁移中执行原始 SQL【英文标题】:How do I execute raw SQL in a django migration 【发布时间】:2015-10-20 07:05:33 【问题描述】:

我知道 Django 中的光标对象。在迁移中是否有其他首选方式来执行原始 SQL?我想为我的一个模型表引入 postgresql 分区。分区逻辑是一堆函数和触发器,必须在设置时添加到数据库中,我想自动化。

【问题讨论】:

【参考方案1】:

一种方式:

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

Migrations 包含 RunSQL 类。为此:

    ./manage.py makemigrations --empty myApp 编辑创建的迁移文件以包括:

operations = [ migrations.RunSQL('RAW SQL CODE') ]

正如 Nathaniel Knight 所提到的,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。所以它可以处理现有的功能。

【讨论】:

有没有办法为 suctom sql 添加向后迁移? 您确实应该将有关 RunSQL 的注释移到顶部。这绝对是最好的方法...... @DataGreed 不确定您是否还想知道,但您可以传递第二个 SQL 字符串用作反向 sql。 请注意,RunSQL 需要安装 sqlparse 库。 作为记录,RunSQL 还接受一个 reverse_sql 参数来反转迁移。有关详细信息,请参阅文档:docs.djangoproject.com/en/1.11/ref/migration-operations/#runsql【参考方案2】:

我会推荐 django-migrate-sql-deux https://pypi.org/project/django-migrate-sql-deux/

通过这种方式,您可以像 Django 中的模型一样以声明方式管理视图、函数、触发器等数据库对象。然后你需要通过makemigrations 生成对 Django 迁移的更改。并通过migrate 应用它们。所以开发和部署流程是一样的。

如果 Django 拥有这个用于原始 SQL“模型”的系统并在 makemigrationsmigratedjango-migrate-sql-deux 这样的命令中自动处理迁移和依赖关系,那就太棒了。

【讨论】:

以上是关于如何在 django 迁移中执行原始 SQL的主要内容,如果未能解决你的问题,请参考以下文章

Django 视图中的原始 SQL 查询

在 django 中获取最后插入的 id

如何通过 Django 迁移执行 git 命令?

如何在 Django 中使用 South 将数据从一个模型迁移到另一个模型?

django迁移问题

django 面试题