Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cross Database foreign key error

This my model of first Database DB1:

     from django.db import models 

     class Company(models.Model): 

          name = models.CharField(max_length=100, null=True)
          address = models.TextField(max_length=200, null=True)
          website = models.CharField(max_length=200, null=True)
          conatct_no = models.CharField(max_length=20, null=True)
          email = models.EmailField(max_length=20, null=True)
          logo = models.FileField(upload_to='logo/', blank=True, null=True)
          created = models.DateTimeField('company created', auto_now_add=True)
          updated = models.DateTimeField('company updated', auto_now=True, null=True)
          def __unicode__(self):  # Python 3: def __str__(self):
                return self.name

Model of 2nd Database Db2:

    from django.db import models

    from leavebuddymaster.models import Company

    class Department(models.Model): 
       company = models.ForeignKey(Company)
       department_name = models.CharField(max_length=50, null=True)
       created = models.DateTimeField('department created', auto_now_add=True)
       updated = models.DateTimeField('department updated', auto_now=True, null=True)
       def __unicode__(self):  # Python 3: def __str__(self):
            return self.department_name

Now when i open the Department table it gives me a error as:

      ProgrammingError at /admin/leavebuddyapp/department/
      (1146, "Table 'leavebuddy_master.leavebuddyapp_department' doesn't exist")

I have done all the settings in settings.py correctly for the two databases. Can you please guide me in the right direction. Thanx in advance.

like image 422
Shivratna Avatar asked Apr 24 '14 12:04

Shivratna


People also ask

Can you have a foreign key in another database?

FOREIGN KEY constraints can reference another column in the same table, and is referred to as a self-reference. A FOREIGN KEY constraint specified at the column level can list only one reference column. This column must have the same data type as the column on which the constraint is defined.

What is a foreign key error?

The error message itself showing there is a foreign key constraint error, which means you are deleting a parent table where the child table contains the Primary table identifier as a foreign key. To avoid this error, you need to delete child table records first and after that the parent table record.

Why foreign key is not recommended?

Having active foreign keys on tables improves data quality but hurts performance of insert, update and delete operations. Before those tasks database needs to check if it doesn't violate data integrity. This is a reason why some architects and DBAs give up on foreign keys at all.

What is foreign key violation in SQL?

It causes violation only if the tuple in relation 1 is deleted which is referenced by foreign key from other tuples of table 2 in the database, if such deletion takes place then the values in the tuple of the foreign key in table 2 will become empty, which will eventually violate Referential Integrity constraint.


1 Answers

You're correct, Django does not currently support foreign key relationships spanning multiple databases. From Cross-database relations [Edit 2020: Django version bump]:

If you have used a router to partition models to different databases, any foreign key and many-to-many relationships defined by those models must be internal to a single database.

This is because of referential integrity. In order to maintain a relationship between two objects, Django needs to know that the primary key of the related object is valid. If the primary key is stored on a separate database, it’s not possible to easily evaluate the validity of a primary key.

A solution I thought up that you could try (though it may present other problems):

from leavebuddymaster.models import Company

class Department(models.Model): 
    company_id = models.IntegerField()
    
    @property
    def company(self):
        return Company.objects.get(pk=self.company_id)

This allows you to refer to Department.company like you normally would in your example. Setting it would just be a matter of Department.company_id = Company.pk. Hope it helps, or at least inspires a better solution!

like image 165
pcoronel Avatar answered Nov 15 '22 04:11

pcoronel