Elgin Cahangirov
Elgin Cahangirov

Reputation: 2022

Django multiple database foreign keys

I am trying to implement multiple database support for my django (version 1.11) app. For that purpose I have included in my settings.py:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'labrin_dbase',
        'USER': 'labrin_admin',
        'PASSWORD': 'ndzwwZHv63STuvAF?C_$L@j@*@epZXaX',
        'HOST': 'localhost',
        'PORT': '5432',
    },
    'comment': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'labrin_dbase_comments',
        'USER': 'labrin_admin_comments',
        'PASSWORD': 'adzwaTHv63STuvAF!C_$L@j@*@epZXaY',
        'HOST': 'localhost',
        'PORT': '5433',
    }
}

DATABASE_ROUTERS = [
    'labrin_task.comment_router.CommentRouter',
]

And my database router is configured as below:

class CommentRouter(object):
    def db_for_read(self, model, **hints):
        if model._meta.db_table == 'todo_comment':
            return 'comment'
        return None

    def db_for_write(self, model, **hints):
        if model._meta.db_table == 'todo_comment':
            return 'comment'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        return True

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if model_name == 'comment':
            return db == 'comment'
        return None

Models in my "todo" app(which is only app in project):

from django.db import models
from django.contrib.auth import get_user_model

UserModel = get_user_model()


class Todo(models.Model):
    name = models.CharField(max_length=64)
    description = models.TextField()
    author = models.ForeignKey(UserModel, on_delete=models.CASCADE)
    deadline = models.DateTimeField()
    created_at = models.DateTimeField(auto_now_add=True)


class Comment(models.Model):
    todo = models.ForeignKey(Todo, on_delete=models.CASCADE)
    author = models.ForeignKey(UserModel, on_delete=models.CASCADE)
    text = models.CharField(max_length=256)
    created_at = models.DateTimeField(auto_now_add=True)


class ShareTodo(models.Model):
    todo = models.ForeignKey(Todo, on_delete=models.CASCADE)
    with_user = models.ForeignKey(UserModel, on_delete=models.CASCADE)
    comment_allowed = models.BooleanField(default=False)

When I remove comment database and DATABASE_ROUTERS from settings.py, my app is working normally. After adding mentioned to settings.py, my app returns an error when I create Comment object. The error says:

Exception inside application: insert or update on table "todo_comment" violates foreign key constraint "todo_comment_author_id_bb272a3e_fk_auth_user_id" DETAIL: Key (author_id)=(1) is not present in table "auth_user". What am I doing wrong?

Note: I am starting two postgres servers as separate docker containers and after running containers, I run python manage.py migrate and python manage.py migrate --database=comment for making all migrations.

Upvotes: 0

Views: 482

Answers (1)

GwynBleidD
GwynBleidD

Reputation: 20569

Sorry, but cross-database relations are not possible to recreate in Django. You can find full explanation in Django docs.

Furthermore, you cannot even do cross-database relations in PostgreSQL so even trying to hack it or to achieve it outside of Django won't be possible. Maybe for other database engines it is possible, you can do your own research.

Upvotes: 1

Related Questions