具有多个应用程序的多个数据库的Django迁移

问题描述 投票:1回答:1

我有一个django项目,其中包含2个应用程序,每个应用程序都在不同的DB上运行(我们称它们为default和DB2)。我创建了一个路由器来管理数据,并将路由器添加到我的settings.py

[当我运行迁移时,我得到Applying analytics.0001_initial... OK,但是在默认数据库中,唯一要更新的是django_migrations表,该表显示应用程序分析已使用0001进行了迁移,而在DB2中,该表本身甚至没有完全创建。

进入django shell并尝试执行obj.objects.all()给我表DB2.table_name不存在我还验证了sql DB2中是否存在,但没有我创建的表

我的路由器:] >>

class DB2Router(object):
    """
    A router for apps that connect directly to the DB2 database.

    This router allows apps to directly update the DB2  database rather
    than using raw SQL as in the past. The router forces the use of the DB2
    database for any app in the "apps" list.
    """
    db = "DB2"
    apps = ["analytics"]

    def db_for_read(self, model, **hints):
        if model._meta.app_label in self.apps:
            return self.db
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label in self.apps:
            return self.db
        return None

    def allow_relation(self, obj1, obj2, **hints):
        # Allow any relation between two models that are both in the same app.
        if (obj1._meta.app_label in self.apps) and (obj2._meta.app_label  in self.apps):
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label in self.apps:
            return db == self.db
        return None

我的模型:

] >>
class PartnerImpression(models.Model):
    """ used to track impressions on widgets through our partners """
    partner = models.CharField(max_length=1024)
    referer = models.CharField(default="N/A", max_length=2048)
    created = models.DateTimeField(auto_now_add=True, blank=True)

迁移:

] >>
class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='PartnerImpression',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('partner', models.CharField(max_length=1024)),
                ('referer', models.CharField(default='N/A', max_length=2048)),
                ('created', models.DateTimeField(auto_now_add=True)),
            ],
        ),
    ]

  • DB2存在并且有一个空的django_migrations表。

  • manage.py migrate --database=DB2命令中定义数据库不是一个选择,因为我在数十台服务器上运行了CI进程,并且无法在所有服务器上手动运行它,因此该命令无需使用任何参数。] >

  • 我在迁移中不需要任何原始SQL

  • [我也发现了这一点:Django migrations with multiple databases,但我不知道自2016年以来是否发生了任何变化,还希望找到一种无需database选项就可以运行的方法

    我有一个django项目,其中包含2个应用程序,每个应用程序都在不同的DB上运行(我们称它们为default和DB2)。我创建了一个路由器来管理数据,并将该路由器添加到我的settings.py中... ... >>

    默认情况下,如果未提供,则migrate--database值设为defaultDEFAULT_DB_ALIAS);因此,将对该数据库应用所有迁移。如果要使用Django提供的即用型功能,则必须使用--database提及要操作的数据库。如果由于某种原因您不能使用它(如您提到的那样),则可以创建一个自定义管理命令,例如migrate_all一次将所有迁移应用于所有数据库。

    下面的示例方法仅显示handle方法的外观,您可以从migrate中获得启发:

    migrate_all.py

    from importlib import import_module
    from django.apps import apps
    from django.db import connections
    
    class Command(BaseCommand):
        help = "Updates all database schemas."
    
        def add_arguments(self, parser):
            # Add arguments if you want
            pass
    
        def handle(self, *args, **options):
            # Import the 'management' module within each installed app, to register
            # dispatcher events.
            for app_config in apps.get_app_configs():
                if module_has_submodule(app_config.module, "management"):
                    import_module('.management', app_config.name)
    
            # Iterate over and operate on each of the databases
            for connection in connections.databases:
                # https://github.com/django/django/blob/master/django/core/management/commands/migrate.py#L84
                connection.prepare_database()
                ...
                ...
    

    connections.databases获得每个连接后,follow the operations from migrations for each。>

django django-models django-migrations
1个回答
0
投票

默认情况下,如果未提供,则migrate--database值设为defaultDEFAULT_DB_ALIAS);因此,将对该数据库应用所有迁移。如果要使用Django提供的即用型功能,则必须使用--database提及要操作的数据库。如果由于某种原因您不能使用它(如您提到的那样),则可以创建一个自定义管理命令,例如migrate_all一次将所有迁移应用于所有数据库。

下面的示例方法仅显示handle方法的外观,您可以从migrate中获得启发:

migrate_all.py

© www.soinside.com 2019 - 2024. All rights reserved.