关于数据库类型的Django Migration RunSQL条件

Ale*_*erg 14 django django-orm django-database django-migrations

我试图使用migrations.RunSQLDjango迁移来运行一些任意的SQL代码.我想仅针对某些db后端运行此迁移(例如仅针对postgres).

我想使用这样的东西,但我没有看到类中的数据库连接信息Migration.

Pau*_*est 8

这是我解决问题的方法,因为我无法RunSQL在里面工作RunPython.值得庆幸的是,该schema_editor对象有一个execute()方法.

def forwards(apps, schema_editor):
    if not schema_editor.connection.vendor.startswith('postgres'):
        logger.info('Database vendor: {}'.format(schema_editor.connection.vendor))
        logger.info('Skipping migration without attempting to ADD CONSTRAINT')
        return

    schema_editor.execute('ALTER TABLE my_table ADD CONSTRAINT my_constraint (my_field != \'NaN\';)')


def backwards(apps, schema_editor):
    if not schema_editor.connection.vendor.startswith('postgres'):
        logger.info('Database vendor: {}'.format(schema_editor.connection.vendor))
        logger.info('Skipping migration without attempting to DROP CONSTRAINT')
        return

    schema_editor.execute('ALTER TABLE my_table DROP CONSTRAINT my_constraint;')


class Migration(migrations.Migration):

    dependencies = [
        ...
    ]

    operations = [
        migrations.RunPython(forwards, backwards, atomic=True)
    ]
Run Code Online (Sandbox Code Playgroud)


Mat*_*hew 6

我只是有同样的需要.我必须编辑一个设置序列初始值的迁移,它适用于postgres但不适用于sqlite.以下是我如何将RunSQL包装在RunPython中,遵循Daniel链接到的文档.

from django.db import migrations


def forwards(apps, schema_editor):
    if not schema_editor.connection.vendor == 'postgres':
        return
    migrations.RunSQL(
        "alter sequence api_consumer_id_seq restart with 1000500;")


class Migration(migrations.Migration):
    dependencies = [
        ('api', '0043_auto_20160416_2313'),
    ]

    operations = [
        migrations.RunPython(forwards),
    ]
Run Code Online (Sandbox Code Playgroud)

  • 问题在于,migrations.RunSQL()返回一个对象。在使用某些参数调用该对象的_run_sql()方法之前,它实际上不会执行任何SQL。请参阅PaulMest的响应以获取也使用migrations.RunPython()方法但以实际执行SQL的方式执行SQL的解决方案。 (2认同)

Sha*_*rog 6

我今天解决了一个类似的问题——需要执行迁移以创建新模型,但仅适用于 postgres 数据库——我发现了这个问题。但是,马修的回答对我没有帮助。事实上,我不确定它是否有效。那是因为 with 行migrations.RunSQL(...)实际上并没有运行SQL;它创建一个类型RunSQL为 a的新对象Command,然后立即丢弃它。

这是我最终解决问题的方法,以防将来有人尝试搜索“django 条件迁移”:

from __future__ import unicode_literals

import django.contrib.postgres.fields
from django.db import migrations, models


class PostgresOnlyCreateModel(migrations.CreateModel):
    def database_forwards(self, app_label, schema_editor, from_state, to_state):
        if schema_editor.connection.vendor.startswith("postgres"):
            super(PostgresOnlyCreateModel, self).database_forwards(app_label, schema_editor, from_state, to_state)

    def database_backwards(self, app_label, schema_editor, from_state, to_state):
        if schema_editor.connection.vendor.startswith("postgres"):
            super(PostgresOnlyCreateModel, self).database_backwards(app_label, schema_editor, from_state, to_state)


class Migration(migrations.Migration):

    dependencies = [
        ...whatever...
    ]

    operations = [
        PostgresOnlyCreateModel(
            name='...whatever...',
            fields=[...whatever...],
        ),
    ]
Run Code Online (Sandbox Code Playgroud)


Dan*_*man 0

schema_editorMigration 类中未提供该信息,而是在传递给 RunPython 操作的属性中提供。有关使用此功能的一些示例,请参阅文档。