postgresql 如何在 Django 迁移中执行原始 SQL

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31698103/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 01:59:18  来源:igfitidea点击:

How do I execute raw SQL in a django migration

djangopostgresqldatabase-partitioningdjango-migrations

提问by David Schumann

I am aware of the cursor object in Django. Is there any other preferred way to execute raw SQL in migrations? I want to introduce postgresql partitioning for one of my models tables. The partition logic is a bunch of functions and triggers that have to be added to the database on setup which I'd like to automate.

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

回答by David Schumann

One way:

单程:

The best way I found to do this is using RunSQL:

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

Migrations contains the RunSQL class. To do this:

Migrations 包含 RunSQL 类。去做这个:

  1. ./manage.py makemigrations --empty myApp
  2. edit the created migrations file to include:
  1. ./manage.py makemigrations --empty myApp
  2. 编辑创建的迁移文件以包括:

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

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

As Nathaniel Knight mentioned, RunSQLalso accepts a reverse_sqlparameter for reversing the migration. See the docs for details

正如 Nathaniel Knight 所提到的,RunSQL它还接受一个reverse_sql用于逆转迁移的参数。有关详细信息,请参阅文档

Another way

其他方式

The way I solved my problem initially was using the post_migratesignal to call a cursor to execute my raw SQL.

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

What I had to add to my app was this:

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

in the __init__.pyof myApp add:

__init__.pymyApp 中添加:

default_app_config = 'myApp.apps.MyAppConfig'

Create a file apps.py:

创建一个文件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)

New file db_partition_triggers.py:

新文件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.'

Now on every manage.py syncdbor manage.py migratethis function is called. So make sure it uses CREATE OR REPLACEand IF NOT EXISTS. So it can handle existing functions.

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

回答by Petr P?ikryl

I would recommend django-migrate-sql-deuxhttps://pypi.org/project/django-migrate-sql-deux/

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

This way you can manage database objects like views, functions, triggers in declarative way like models in Django. Then you need generate changes into Django migrations through makemigrations. And apply them via migrate. So the development and deploy flow is pretty same.

通过这种方式,您可以像 Django 中的模型一样以声明方式管理视图、函数、触发器等数据库对象。然后你需要通过makemigrations. 并通过migrate. 所以开发和部署流程非常相似。

It would be awesome if Django would have this system for raw SQL "models" and handle migrations and dependencies automatically in makemigrationsand migratecommands like django-migrate-sql-deux.

这将是真棒,如果Django的将自动拥有该系统的原始SQL“模型”和手柄迁移和依赖makemigrationsmigrate喜欢命令Django的迁移-SQL德塞夫勒