#13946 closed (fixed)
Database caching doesn't account for multiple databases
Reported by: | tiemonster | Owned by: | nobody |
---|---|---|---|
Component: | Core (Cache system) | Version: | 1.2 |
Severity: | Keywords: | multidb database caching | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Database caching doesn't account for multiple databases. As such, when running unit tests, it attempts to create the cache table twice on the default database connection, causing a unit test failure.
Two database connections were defined: default and datastore. CACHE_BACKEND = "db://cache_table" Error was as follows:
Traceback (most recent call last): File "./manage.py", line 11, in <module> execute_manager(settings) File "/usr/local/lib/python2.6/dist-packages/Django-1.2.1-py2.6.egg/ django/core/management/__init__.py", line 438, in execute_manager utility.execute() File "/usr/local/lib/python2.6/dist-packages/Django-1.2.1-py2.6.egg/ django/core/management/__init__.py", line 379, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/usr/local/lib/python2.6/dist-packages/Django-1.2.1-py2.6.egg/ django/core/management/base.py", line 191, in run_from_argv self.execute(*args, **options.__dict__) File "/usr/local/lib/python2.6/dist-packages/Django-1.2.1-py2.6.egg/ django/core/management/base.py", line 218, in execute output = self.handle(*args, **options) File "/usr/local/lib/python2.6/dist-packages/Django-1.2.1-py2.6.egg/ django/core/management/commands/test.py", line 37, in handle failures = test_runner.run_tests(test_labels) File "/usr/local/lib/python2.6/dist-packages/Django-1.2.1-py2.6.egg/ django/test/simple.py", line 313, in run_tests old_config = self.setup_databases() File "/usr/local/lib/python2.6/dist-packages/Django-1.2.1-py2.6.egg/ django/test/simple.py", line 270, in setup_databases connection.creation.create_test_db(self.verbosity, autoclobber=not self.interactive) File "/usr/local/lib/python2.6/dist-packages/Django-1.2.1-py2.6.egg/ django/db/backends/creation.py", line 358, in create_test_db call_command('createcachetable', cache_name) File "/usr/local/lib/python2.6/dist-packages/Django-1.2.1-py2.6.egg/ django/core/management/__init__.py", line 166, in call_command return klass.execute(*args, **defaults) File "/usr/local/lib/python2.6/dist-packages/Django-1.2.1-py2.6.egg/ django/core/management/base.py", line 218, in execute output = self.handle(*args, **options) File "/usr/local/lib/python2.6/dist-packages/Django-1.2.1-py2.6.egg/ django/core/management/base.py", line 318, in handle label_output = self.handle_label(label, **options) File "/usr/local/lib/python2.6/dist-packages/Django-1.2.1-py2.6.egg/ django/core/management/commands/createcachetable.py", line 50, in handle_label curs.execute("\n".join(full_statement)) File "/usr/local/lib/python2.6/dist-packages/Django-1.2.1-py2.6.egg/ django/db/backends/mysql/base.py", line 86, in execute return self.cursor.execute(query, args) File "/usr/lib/pymodules/python2.6/MySQLdb/cursors.py", line 166, in execute self.errorhandler(self, exc, value) File "/usr/lib/pymodules/python2.6/MySQLdb/connections.py", line 35, in defaulterrorhandler raise errorclass, errorvalue _mysql_exceptions.OperationalError: (1050, "Table 'cache_table' already exists")
In my situation, our datastore was a read-only connection. I told Django to treat it as a replication slave using the TEST_MIRROR setting, and the error went away. This won't work for all setups, however. For more information, see discussion on django-users here.
Change History (6)
comment:1 by , 14 years ago
milestone: | → 1.3 |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 14 years ago
comment:3 by , 14 years ago
It's not just the overhead I'm concerned about (although that is a mild concern). It's the mechanics of getting a model installed.
- The database table name is only available via settings.py
- and only then *if* the database cache backend is being used;
- there isn't a models.py to put the model file in.
I suppose the other approach would be to use the router, but use a dummy model that can be clearly identified - i.e, a class that quacks like a normal Django model, but is actually a representation of the database cache model. The 'cache model' wouldn't actually be used for database operations; it would just provide the metadata that the router requires. That way we step outside the usual app/models registration process, but can use the simple interface for routing purposes.
comment:4 by , 14 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
To me this is a strong argument for moving the DB caching to use the ORM, this is and non-SQL databases. I realize this entails some overhead, but really if you have performance problems you shouldn't be using a DB cache.