迁移Django模型到PostgreSQL架构

5
我希望在特定的Postgresql模式(即“schema1”)中创建一个新表,从Django迁移开始。尽管按照此博客此帖子的方法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://dev59.com/plUL5IYBdhLWcg3wHU_M#51007441
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中根本无法实现?
2个回答

3

当运行迁移时,您必须明确提供数据库定义的名称:

$ python manage.py migrate legacydbapp --database schema1

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


谢谢,一旦我指定了 --database schema1,这个方法就起作用了。然而,我不需要实现 allow_migrate()。如果我正确理解文档的话,这将是一个保障措施,可以在未经授权的模式中静默地防止迁移应用(例如,在忘记使用 --database schema1 指定数据库的情况下)。如果您能确认这一点,或者指出没有实现任何 allow_migrate() 函数存在其他风险,我将不胜感激。 - sc28
1
这也是我的理解。如果你总是带有应用名称和数据库参数调用migrate,那么你可能不需要实现allow_migrate。然而,如果你不带任何参数调用migrate,它将会应用所有应用的迁移,包括你的legacydbapp - Daniel Hepper
这对我不起作用。我得到了 django.db.utils.ConnectionDoesNotExist: The connection schema1 doesn't exist - Stefan_EOX
是的,我知道,但数据库叫做postgres,并且有多个模式。我为了与您的答案保持一致使用了schema1 - Stefan_EOX
在我的情况下,我首先必须手动创建模式schema1。然后迁移才能生效。 - Stefan_EOX
显示剩余2条评论

-2

嗨,要将一个模型迁移到特定的架构,你可以使用:

python manage.py migrate -s schema1

我在 Django 文档中没有看到这个。你从哪里得到了 -s 参数? - spideyclick
在Django 4中,"python manage.py migrate -s schema1"。 - Youssri Abo Elseod
我不明白为什么这个答案被标记为无用。兄弟,你真是救了我一天。我只是想为PostgreSQL的备用搜索创建一个虚拟模式。这个命令简直太好用了。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接