【问题标题】:Can migrations.RunPython run arbitrary python code?migrations.RunPython 可以运行任意 python 代码吗?
【发布时间】:2015-09-20 11:15:13
【问题描述】:

我想在迁移结束时包括对许多原始 SQL 文件(函数、触发器...)的处理。

我想写我的own Special operation,但有人告诉我改用django.db.migrations.RunPython() 命令并将一些 django.db.migrations.RunSQL() 命令放在被调用的函数中。

由于 RunPython() 需要一个带有 2 个实例(一个应用程序和一个 SchemaEditor)的可调用对象,我严重怀疑(我查看了一点源代码)我可以用纯 Python 代码调用一个函数,它似乎只能执行 ORM操纵。我应该在 RunPython 中使用 execute_from_command_line() 吗?还是这种方式注定要失败?还是做事不好?

from __future__ import unicode_literals
from django.db import migrations

def load_sql(apps, schema_editor):

    from os.path import normpath, dirname, isfile, join
    from os import listdir

    sql_folder_path = '/backoffice/sql/'

    def load_raw_sql(folder_inside):
        folder_path = join(sql_folder_path, folder_inside)
        sql_files = [join(folder_path, f) for f in listdir(folder_path) if isfile(join(folder_path, f))]
        for sql_file in sql_files:
            with open(sql_file, 'r') as g:
                migrations.RunSQL(g.read())

    folders = ['functions', 'index', 'triggers']

    for folder in folders:
        load_raw_sql(folder)


class Migration(migrations.Migration):
    dependencies = [
        ('app1', '0001_squashed_0018_auto_20150616_0708'),
    ]

    operations = [
        migrations.RunPython(load_sql),
    ]

我们正在使用 PostGreSQL。 提前感谢您的回答。

【问题讨论】:

  • “我严重怀疑......我可以用纯 python 代码调用一个函数,它似乎只能执行 ORM 操作。”这句话真的把我扔了。纯 Python 与仅 ORM 操作是什么意思?所有的 Django 都是用 Python 编写的。什么是“不纯”的?
  • 用词不当,但我的意思是我只在 runPython() 命令中看到了类似模型的实现,我想知道我是否可以在其中编写任何 python 代码?
  • 大概。你试过了吗?什么会阻止你?甚至那些模型也只是 Python 代码。
  • 我试过上面的代码,好像我做错了,如果我放打印语句,我没有得到任何输出,我的 django_migrations 表得到一个迁移条目运行代码,所以它不会失败。我不知道我是否需要 link sqlparse 包以及我应该使用 RunSQL 还是手动使用数据库连接。

标签: python django django-migrations


【解决方案1】:

我认为很明显一个名为 RunPython 的操作可以,呃,运行 python 代码,但简短的回答是肯定的,你可以在 RunPython 操作中做任何你想做的事情。

要考虑的主要事情是,您编写的代码需要在将来继续工作(或直到您压缩迁移),因为每次运行 migratemakemigrations 时,所有先前的迁移都用于派生数据库的当前状态。

【讨论】:

  • 谢谢,所以我应该假设是我的代码坏了对吧?
【解决方案2】:

django.db.migration.RunPython 可以接受任何 python 代码。 这里的问题是我尝试在使用 RunPython() 进行的调用中使用 RunSQL(),这在我的情况下似乎不起作用,因为我没有提供应用程序和模式编辑器。 多亏了一个游标,我设法运行了一批 SQL 文件,并在我的可调用对象中写入:

from django.db import migrations
cursor = connections['default'].cursor()
sql = "FOO;"
cursor.execute(sql)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-01
    • 1970-01-01
    • 2018-09-30
    相关资源
    最近更新 更多