Skip to content

Deleting user object in multiple database environment, raises exception #85

@gauravvjn

Description

@gauravvjn

Env:

  • Python 2.7
  • Django==1.7.10
  • django-fsm==2.6.0
  • django-fsm-log==1.3.0

Scenario:

  • A django project with two Apps (app1 & app2).
  • We have two databases(DB1, DB2) configured as well (check below DB router configuration).
  • Tables which are part of app2, will be created in the DB2.
    (python manage.py migrate app2 --database=DB2)
  • And app1 tables in DB1 database, which is a default database.
    (python manage.py migrate app1)
  • Both DBs have the user, group, permission and auth tables.
  • Installdjango_fsm_log in 2nd DB only (i.e. DB2).
    (python manage.py migrate django_fsm_log --database=DB2)

Now try to delete a user object in the app1, This user object is coming from DB1. you will get an Error saying,
ProgrammingError: (1146, "Table 'DB1.django_fsm_log_statelog' doesn't exist") which is True.
we don't have that table in DB1 but in DB2.

After investigating we found that it tries to delete user.statelog__set and fail.

Source code
DB router configuration: database_router.py

class DB2Router(object):
    APP_LABEL_LIST = ['app2, 'django_fsm_log']

    def db_for_read(self, model, **hints):
        if model._meta.app_label in self.APP_LABEL_LIST:
            return DB2
        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label in self.APP_LABEL_LIST:
            return DB2
        return None

    def allow_relation(self, obj1, obj2, **hints):
        if set(self.APP_LABEL_LIST) & set([obj1._meta.app_label, obj2._meta.app_label]):
            return obj1._meta.app_label == obj2._meta.app_label
        return None

    def allow_migrate(self, db, model):
        if model._meta.app_label in self.APP_LABEL_LIST:
            return db == DB2
        return None

And in settings

DATABASE_ROUTERS = [
    'database_router.DB2Router',
]

Even after having database_router configured, it is happening.
What can be done here? is there any way in our library to remove this constraint or set ON_DELETE attribute dynamically.

Error Traceback:

File "/home/local/lib/python2.7/site-packages/django/db/models/base.py", line 738, in delete
File "/home/local/lib/python2.7/site-packages/django/db/models/deletion.py", line 198, in collect
File "/home/local/lib/python2.7/site-packages/django/db/models/query.py", line 145, in __nonzero__
File "/home/local/lib/python2.7/site-packages/django/db/models/query.py", line 966, in _fetch_all
File "/home/local/lib/python2.7/site-packages/django/db/models/query.py", line 265, in iterator
File "/home/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 701, in results_iter
File "/home/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 787, in execute_sql
File "/home/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
File "/home/local/lib/python2.7/site-packages/django/db/utils.py", line 94, in __exit__
File "/home/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
File "/home/local/lib/python2.7/site-packages/django/db/backends/mysql/base.py", line 129, in execute
File "/home/local/lib/python2.7/site-packages/MySQLdb/cursors.py", line 205, in execute
File "/home/local/lib/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions