Django 迁移不使用配置的数据库连接

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

我正在使用 supabase postgresql 和 django。默认情况下它使用公共模式,但现在我想将模型中的 user_id 字段链接到 auth.users.id ,其中 auth 是模式,users 是表名称,id 是 UUID 字段

模型定义在这里

# auth/models.py
class SupabaseUser(models.Model):
    id = models.UUIDField(
        primary_key=True,
        default=uuid.uuid4,
        verbose_name="User ID",
        help_text="Supabase managed user id",
        editable=False,
    )

    class Meta:
        managed = False
        db_table = "users"
# myapp/models.py
class MyModel(models.Model):
   user = models.ForeignKey(
        SupabaseUser,
        on_delete=models.CASCADE,
        verbose_name="Supabase User",
        help_text="Supabase user associated with the account",
        null=False,
    )

在设置中我有两个数据库连接

DATABASES = {
    "default": dj_database_url.config(),
    "supabase_auth": dj_database_url.config(),
}
DATABASES["supabase_auth"]["OPTIONS"] = {
    "options": "-c search_path=auth",
}

当然型号路由器配置为

from django.db.models import Model
from django.db.models.options import Options


class ModelRouter:
    @staticmethod
    def db_for_read(model: Model, **kwargs):
        return ModelRouter._get_db_schema(model._meta)

    @staticmethod
    def db_for_write(model: Model, **kwargs):
        return ModelRouter._get_db_schema(model._meta)

    @staticmethod
    def allow_migrate(db, app_label, model: Model, model_name=None, **kwargs):
        return True

    @staticmethod
    def _get_db_schema(options: Options) -> str:
        if options.app_label == "auth":
            return "supabase_auth"
        return "default"

当我使用

./manage.py shell
并运行以下脚本时,它可以工作

from auth.models import SupabaseUser
assert SupabaseUser.objects.count() == 1

但是当我为

myapp
申请迁移时,我收到以下错误

$ ./manage.py makemigration myapp && ./manage.py migrate myapp
Operations to perform:
  Apply all migrations: myapp
Running migrations:
  Applying myapp.0013_mymodel_user...Traceback (most recent call last):
  File "/mnt/Projects/myapp/backend/.venv/lib/python3.11/site-packages/django/db/backends/utils.py", line 103, in _execute
    return self.cursor.execute(sql)
           ^^^^^^^^^^^^^^^^^^^^^^^^
psycopg2.errors.UndefinedTable: relation "users" does not exist
....
snip
....
django.db.utils.ProgrammingError: relation "users" does not exist
python django orm
1个回答
0
投票

实际上我可以使用

migrations.RunSQL

解决这个问题
from django.db import migrations


class Migration(migrations.Migration):
    dependencies = [
        ("auth", "0001_initial"),
        ("myapp", "0012_alter_mymodel_some_field"),
    ]

    operations = [
        migrations.RunSQL(
            sql=(
                "ALTER TABLE myapp_mymodel ADD COLUMN user_id UUID;",
                "ALTER TABLE myapp_mymodel ADD CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES auth.users (id) ON DELETE CASCADE;",
            ),
            reverse_sql=(
                "ALTER TABLE myapp_mymodel DROP CONSTRAINT fk_user_id;",
                "ALTER TABLE myapp_mymodel DROP COLUMN user_id;",
            ),
        ),
    ]

在此,每当应用迁移时都会执行

sql
字段,而每当恢复迁移时都会执行
reverse_sql
。反向 SQL 是可选的,但通常添加它是为了清理迁移中的混乱。

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