如何使用多对多关系与不同 PostgreSQL 模式中的表创建 Django 模型,一个模型仅使用非托管表的一部分

我有一个运行良好的 Django 应用程序。问题是它需要迁移并带来一些变化。

整个应用程序过去都在 PostgreSQL 模式中。
问题在于以下模型。

class Authority(models.Model):
    id = models.IntegerField(primary_key=True)
    code = models.IntegerField()
    name = models.CharField(max_length=255)

class Doc(behaviors.Timestampable):
    id = models.IntegerField(primary_key=True)
    authorities = models.ManyToManyField(Authority, related_name="docs", )

我需要权限模型来使用名为 authority_list 的现有表。表位于不同的模式命名列表中,它包含许多列。我只需要其中的三个。Table 也被其他应用程序使用,仅用于阅读。

我尝试像这样创建路由器:

ROUTED_MODELS = [models.Authority]

class DefaultRouter:
    def db_for_read(self, model, **hints):
        if model in ROUTED_MODELS:
            return 'lists'
        return None

    def db_for_write(self, model, **hints):
        if model == models.Authority:
            raise Exception("This model is read only!")
        return None

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'OPTIONS': {
            'options': '-c search_path=intake,lists,public'
        },
        'NAME': 'dmx',
        'USER': 'postgres',
        'HOST': 'localhost',
    },
    'lists': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'OPTIONS': {
            'options': '-c search_path=lists,intake,public'
        },
        'NAME': 'dmx',
        'USER': 'postgres',
        'HOST': 'localhost',
    },
DATABASE_ROUTERS = ('dmx.db_routers.DefaultRouter',)

更改权限模型

class Authority(models.Model):
    class Meta:
        managed = False
        db_table = "authority_list"

它没有像我想要的那样工作,所以我在某个地方发现了这种语法'lists\".\"authority_list'也不起作用。

无论我尝试什么 Django 总是在摄入模式中创建表 authority_list。
并且因为关系是多对多的,所以 Django 创建连接表来链接intake.authority_list 而不是lists.authority_list。

我找到的唯一解决方案是在模式摄入中创建视图,从lists.authority_list 中选择我需要的那 3 列。但是后来有人告诉我不能使用视图。表lists.authority_list 会定期(每周一次)以删除和重新创建表的方式更新。在我看来这不是一个好习惯,但我无法改变它。

有什么方法可以做到吗?

回答我自己的问题:其实很简单。

问题在于生成的迁移与模型语法无关。由于我的应用程序尚未投入生产,因此我可以删除所有迁移和数据库并重新创建它们。这有帮助,现在它按我的预期工作。

你唯一需要的是:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'OPTIONS': {
            'options': '-c search_path=intake,lists,public'
        },
        'NAME': 'dmx',
        'USER': 'postgres',
        'HOST': 'localhost',
    },

和型号

class Authority(models.Model):
    id = models.IntegerField(primary_key=True)
    code = models.IntegerField()
    name = models.CharField(max_length=255)

    class Meta:
        managed = False
        db_table = "authority_list"

你不需要写你的路由器。只需将架构(在我的情况下为列表)添加到您的 DATABASES OPTIONS 中。您不需要使用(可能已弃用?)这样的语法db_table = 'lists\".\"authority_list'并且可以不使用表列中的所有字段。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章