Alex Rivera | Logout

How to work around lack of support for foreign keys across databases in Django

Asked 2011-03-30T22:29:31.240
78

I know Django does not support foreign keys across multiple databases (originally Django 1.3 docs)

But I'm looking for a workaround.

What doesn't work

I have two models each on a separate database.

routers.py:

class NewsRouter(object):
    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'news_app':
            return 'news_db'
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label == 'news_app':
            return 'news_db'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        if obj1._meta.app_label == 'news_app' or obj2._meta.app_label == 'news_app':
            return True
        return None

    def allow_syncdb(self, db, model):
        if db == 'news_db':
            return model._meta.app_label == 'news_app'
        elif model._meta.app_label == 'news_app':
            return False
        return None

Model 1 in fruit_app/models.py:

from django.db import models

class Fruit(models.Model):
    name = models.CharField(max_length=20)

Model 2 in news_app/models.py:

from django.db import models

class Article(models.Model):
    fruit = models.ForeignKey('fruit_app.Fruit')
    intro = models.TextField()

Trying to add a "Article" in the admin gives the following error because it is looking for the Fruit model on the wrong database ('news_db'):

DatabaseError at /admin/news_app/article/add/

(1146, "Table 'fkad_news.fruit_app_fruit' doesn't exist")

Method 1: subclass IntegerField

I created a custom field, ForeignKeyAcrossDb, which is a subclass of IntegerField. Code is on github at: django django-models django-orm

Edit
Report

1 Answer

2

As to the ForeignKeyAcrossDb part, couldn't you possibly make some adjustments to your class inside __init__? Check if the appropriate field is Integer if not, load it from the database, or do anything else that is required. Python __class__es can be changed at runtime without much problem.

answered 2011-04-14T15:11:47.930

Your Answer