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.