jazzband / django-fsm-log

Automatic logging for Django FSM

Home Page:https://django-fsm-log.readthedocs.io/en/latest/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Deleting user object in multiple database environment, raises exception

gauravvjn opened this issue · comments

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

Do you have a traceback for when it fails?

Now in the app, try to delete a user object which is coming from DB1

Shouldn't that cause a traceback then also?

Anyway, I've not investigated into this really - just thought that it would be useful for when doing so.

Without the code there, please also provide your versions of Django, django-fsm-log and Python (at least).

@blueyed: Added required details in the description.