Opened 14 years ago
Closed 13 years ago
#14610 closed New feature (fixed)
fixtures should be able to specify their database
Reported by: | cyberlogi | Owned by: | nobody |
---|---|---|---|
Component: | Testing framework | Version: | 1.2 |
Severity: | Normal | Keywords: | |
Cc: | brenthoover | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I have a product that has two databases, one is the member related database and the other is a 10gb static database. For performance reasons, I have to keep them separate and I have a database router which handles this. For testing purposes I need to load both databases for some of my function and view tests. The initial load of the test databases works correctly and I have two separate test databases, but when I specify fixtures in my TestCase, they all run against the default database, which causes the fixtures to fail to load.
After spending the last 24 hours diving through the Django source code and talking to other developers, I cannot find a way to specify the database on which a fixture should load (when the 'syncdb' command is executed). This seems like a feature that should be build into fixtures (or the TestCase framework), otherwise developers can't test code that runs against multiple databases.
My database setup is:
DATABASES = { 'default': { 'NAME': 'matt', 'ENGINE': 'mysql', 'USER': 'myuser', 'PASSWORD': 'changeit', 'HOST': '' }, 'voters': { 'NAME': 'voters', 'ENGINE': 'mysql', 'USER': 'myuser', 'PASSWORD': 'changeit', 'HOST': '' } }
Here is my simple router:
from django.conf import settings class VotizenRouter(object): """A router to control all database operations on models in the myapp application""" def db_for_read(self, model, **hints): "Point all operations on myapp models to 'other'" if model._meta.app_label == 'verifier': return 'voters' return None def db_for_write(self, model, **hints): "Point all operations on myapp models to 'other'" if model._meta.app_label == 'verifier': return 'voters' return None def allow_relation(self, obj1, obj2, **hints): "Allow any relation if a model in myapp is involved" if obj1._meta.app_label == 'verifier' or obj2._meta.app_label == 'verifier': return True return None def allow_syncdb(self, db, model): "Make sure the myapp app only appears on the 'other' db" if db == 'voters': return model._meta.app_label == 'verifier' elif model._meta.app_label == 'verifier': return False return None
The 'db' should be 'voters' when the 'app_label' of the model is 'verifier'. Since the fixture loading logic has the database set to 'default' it fails to load the fixture. For testing purposes I rewrote the 'allow_syncdb' function to always return None and as expected Django attempted to write the fixtures to the 'default' databases, instead of the one specified by the router.
Change History (5)
comment:1 by , 14 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:2 by , 14 years ago
Severity: | → Normal |
---|---|
Type: | → New feature |
comment:4 by , 13 years ago
Cc: | added |
---|---|
UI/UX: | unset |
According to the docs, this feature already exists (in 1.3)
https://docs.djangoproject.com/en/1.3/ref/django-admin/#database-specific-fixtures
Database-specific fixtures
If you are in a multi-database setup, you may have fixture data that you want to load onto one database, but not onto another. In this situation, you can add database identifier into . If your DATABASES setting has a 'master' database defined, you can define the fixture mydata.master.json or mydata.master.json.gz. This fixture will only be loaded if you have specified that you want to load data onto the master database.
So it would seem that the syntax is already prescribed for multi-db fixtures. However, from my experience this does not work correctly, or at least always. I found this looking for an existing bug report before submitting one. However it is in here as a feature request and I do not feel qualified to change it to a bug.
comment:5 by , 13 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Indeed, the problem originally described here is fixed.
If you find a bug, please open a separate ticket, and provide enough information for someone else to reproduce the problem.
Sounds like a reasonable idea to me. Can you propose a syntax for fixtures to specify DB?
P.S. You don't actually need to explicitly "return None", function which is not returning anything is returning None anyway.