【问题标题】:Migrate Django model to Postgresql schema将 Django 模型迁移到 Postgresql 模式
【发布时间】:2019-07-12 02:17:13
【问题描述】:

我想通过 Django 迁移在特定 Postgresql 架构(即“schema1”)中创建一个新表。

尽管遵循this blogthis post 中的方法1,迁移将表发送到默认架构“public”而不是“schema1”。

settings.py,我有:

DATABASES = {

    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'OPTIONS': {
                        'options': '-c search_path=django,public'
                    },
        'NAME': 'myDB',
        'USER': 'username',
        'PASSWORD': '***',
        'HOST': 'my.host.address',
        'PORT': '1234',
    },

    'schema1': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'OPTIONS': {
                    'options': '-c search_path=schema1,public'
                },
    'NAME': 'myDB',
    'USER': 'username',
    'PASSWORD': '***',
    'HOST': 'my.host.address',
    'PORT': '1234',
    } 
}  


#Path to DBrouter to handle PG schemas https://stackoverflow.com/a/51007441/3976696
DATABASE_ROUTERS = ('djangogirls.dbrouters.MyDBRouter',)

djangogirls/dbrouters.py,我有:

from legacydbapp.models import MyUser

# Include here any class (i.e. table) that belongs to the schema "schema1"
ROUTED_MODELS_SCHEMA1 = [MyUser]


class MyDBRouter(object):
    """
    A router to place DB queries into correct schema depending on considered tables.
    """
    def db_for_read(self, model, **hints):
        if model in ROUTED_MODELS_SCHEMA1 :
            return 'schema1'
        return None

    def db_for_write(self, model, **hints):
        if model in ROUTED_MODELS_SCHEMA1 :
            return 'schema1'
        return None

还有我正在尝试迁移的模型类,位于models.py

class MyUser(models.Model):
    first_name = models.CharField(max_length=30, default='',null=True, blank=True) 
    last_name = models.CharField(max_length=30, default='', null=True, blank=True)
    profession = models.CharField(max_length=32,default='', null=True, blank=True)
    def __str__(self):
        return self.first_name + " " + self.last_name
    class Meta:
        managed = True
        db_table = 'myuser'

我运行了以下命令:

$ python manage.py makemigrations legacydbapp
$ python manage.py sqlmigrate legacydbapp 0001_initial
$ python manage.py migrate legacydbapp

而 sqlmigrate 返回以下 SQL:

BEGIN;
--
-- Create model MyUser
-- 
CREATE TABLE "myuser" (
    "id" serial NOT NULL PRIMARY KEY, 
    "first_name" varchar(30) NULL, 
    "last_name" varchar(30) NULL, 
    "profession" varchar(32) NULL); 
COMMIT;

如果 DB 路由器正常工作,我希望 SQL 改为读取 CREATE TABLE "schema1.myuser",但事实并非如此。我是不是在某个地方搞砸了,或者这在 Django 2.1.5 中根本无法实现?

【问题讨论】:

    标签: django postgresql database-schema


    【解决方案1】:

    您必须在运行 migrate 时明确提供数据库定义的名称:

    $ python manage.py migrate legacydbapp --database schema1
    

    为确保模型MyUser仅在特定数据库中创建,您的路由器必须实现.allow_migrate()

    【讨论】:

    • 谢谢,一旦我指定了--database schema1,它就起作用了。但是,我不需要实现allow_migrate()。如果我正确理解文档,这将是一种安全措施,可以默默地防止迁移应用于未经授权的模式(例如,以防忘记使用--database schema1 指定数据库)。如果您能确认这一点,我将不胜感激,或者指出是否存在未实现任何 allow_migrate() 功能的任何其他风险。
    • 这也是我的理解。如果你总是用 appname 和数据库参数调用migrate,你可能不需要实现allow_migrate。但是,如果您在没有任何参数的情况下调用 migrate,它将应用来自所有应用程序的迁移,包括您的 legacydbapp
    • 这对我不起作用。我得到django.db.utils.ConnectionDoesNotExist: The connection schema1 doesn't exist
    • @Stefan_Fairphone 您必须将 schema1 替换为您的 DATABASES 设置中的适当连接名称
    • 是的,我知道,但是数据库名为 postgres 并且有多个模式。我使用schema1 是为了符合您的回答。
    猜你喜欢
    • 1970-01-01
    • 2018-07-19
    • 2015-06-18
    • 2021-12-29
    • 2012-01-05
    • 2019-09-09
    • 2017-05-01
    • 1970-01-01
    • 2012-12-26
    相关资源
    最近更新 更多