Problems on using multiple databases

137 views
Skip to first unread message

Jim

unread,
Aug 22, 2011, 7:31:52 PM8/22/11
to django...@googlegroups.com
Hello folks,

I am learning to set up multiple databases routing in Django.

Before I started, I had everything working properly. Then, I wrote dbrouter.py under the site directory, basically by copying the example in the Django document about using multiple databases. Here is what's in dbrouter.py:
#------------------------------------------------------------------------------------------------------------------------------------
class DBRouter(object):
    def db_for_read(self, model, **hints):
        label = model._meta.app_label
        if label == 'books':
            dbName = 'test' # dbName is a name in settings.DATABASES
        else:
            dbName = None
        return dbName

    def db_for_write(self, model, **hints):
        label = model._meta.app_label
        if label == 'books':
            dbName = 'test'
        else:
            dbName = None
        return dbName

    def allow_syncdb(self, db, model):
        # db is a string of database name.
        label = model._meta.app_label
        if label == 'books':
            dbName = 'test'
        else:
            dbName = None
        return dbName == db
#------------------------------------------------------------------------------------------------------------------------------------

As you can see from dbrouter.py, I have an app called books. 

Here is the DATABASES setting:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': dbPath + os.sep + 'default.sqlite',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
    },
    'test': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': dbPath + os.sep + 'test.sqlite',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
    }
}


Then, I added the following setting to settings.py.
DATABASE_ROUTERS = [siteName + '.dbrouter.DBRouter']

Finally, I ran ./manage.py syncdb. And got these error messages:

>$ ./manage.py syncdb
Creating tables ...
Traceback (most recent call last):
  File "./manage.py", line 17, in <module>
    execute_manager(settings)
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/core/management/__init__.py", line 438, in execute_manager
    utility.execute()
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/core/management/__init__.py", line 379, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/core/management/base.py", line 191, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/core/management/base.py", line 220, in execute
    output = self.handle(*args, **options)
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/core/management/base.py", line 351, in handle
    return self.handle_noargs(**options)
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/core/management/commands/syncdb.py", line 109, in handle_noargs
    emit_post_sync_signal(created_models, verbosity, interactive, db)
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/core/management/sql.py", line 190, in emit_post_sync_signal
    interactive=interactive, db=db)
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/dispatch/dispatcher.py", line 172, in send
    response = receiver(signal=self, sender=sender, **named)
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/contrib/auth/management/__init__.py", line 30, in create_permissions
    ctype = ContentType.objects.get_for_model(klass)
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/contrib/contenttypes/models.py", line 38, in get_for_model
    defaults = {'name': smart_unicode(opts.verbose_name_raw)},
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/db/models/manager.py", line 135, in get_or_create
    return self.get_query_set().get_or_create(**kwargs)
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/db/models/query.py", line 378, in get_or_create
    return self.get(**lookup), False
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/db/models/query.py", line 344, in get
    num = len(clone)
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/db/models/query.py", line 82, in __len__
    self._result_cache = list(self.iterator())
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/db/models/query.py", line 273, in iterator
    for row in compiler.results_iter():
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 680, in results_iter
    for rows in self.execute_sql(MULTI):
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 735, in execute_sql
    cursor.execute(sql, params)
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/db/backends/util.py", line 34, in execute
    return self.cursor.execute(sql, params)
  File "/Users/jianbao/projects/tao.com/mysite/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 234, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.DatabaseError: no such table: django_content_type

Any help would be appreciated. Thank you very much.

Jim

Jim

unread,
Aug 23, 2011, 6:53:32 PM8/23/11
to django...@googlegroups.com
Still stuck on this problem. Can anybody help me out, please? It would be much appreciated.

Reinout van Rees

unread,
Aug 24, 2011, 4:15:06 AM8/24/11
to django...@googlegroups.com
On 23-08-11 01:31, Jim wrote:
> def allow_syncdb(self, db, model):
> # db is a string of database name.
> label = model._meta.app_label
> if label == 'books':
> dbName = 'test'
> else:
> dbName = None
> return dbName == db

I'd do the "if" part as follows:

if label == 'books':
if db == 'test':
return True
return False
if db == 'test':
return False
return None # None means 'no opinion'.

iirc allow_syncdb() ought to return True/False to indicate whether a
certain model should be synced to a certain database. So you need to
make sure *two* things:

- Your special models only end up in your special database and not in
another.

- Other models (like the django_content_type table that gives you
problems!) should not end up in your special deatabase.

Reinout

--
Reinout van Rees http://reinout.vanrees.org/
rei...@vanrees.org http://www.nelen-schuurmans.nl/
"If you're not sure what to do, make something. -- Paul Graham"

Reinout van Rees

unread,
Aug 24, 2011, 4:48:00 AM8/24/11
to django...@googlegroups.com
On 23-08-11 01:31, Jim wrote:
> django.db.utils.DatabaseError: no such table: django_content_type

Which django version, btw? Early 1.2 beta versions had a bug:

https://code.djangoproject.com/ticket/12999

Jianbao Tao

unread,
Aug 24, 2011, 11:57:07 AM8/24/11
to django...@googlegroups.com
Thank you, Reinout.

I changed the definition of 'allow_syncdb' to the following:
<code>
    def allow_syncdb(self, db, model):
        # db is a string of database name.
        label = model._meta.app_label
        if label == 'books':
            dbName = 'test'
        else:
            dbName = None
        if dbName == db:
            return True
        else:
            return None
</code>

Now './manage.py syncdb' can run through with no problems. However, it doesn't create the database 'test.sqlite', which means the models in the app, books, are still installed in the default database. 

Also, I am using django v1.3.

In addition, about the *two* things you mentioned, how can I test for that? It seems all the functions defined in the class DBRouter are called internally by django. I don't know how to make django print something so that I know what's going on when django calls those function.

Again, thank you very much.




--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.


Reinout van Rees

unread,
Aug 24, 2011, 12:13:14 PM8/24/11
to django...@googlegroups.com
On 24-08-11 17:57, Jianbao Tao wrote:
> Now './manage.py syncdb' can run through with no problems. However, it
> doesn't create the database 'test.sqlite', which means the models in the
> app, books, are still installed in the default database.
>

That's in the django docs: syncdb only managed the main default database
by default. You'll have to call syncdb on the second database separately.

Often the second database is an existing one that django shouldn't
touch, that's why the default is that way.

Jianbao Tao

unread,
Aug 24, 2011, 8:36:52 PM8/24/11
to django...@googlegroups.com
Reinout, 

Thanks so much for your help. I think I have figured out the solution. I posted it on https://groups.google.com/forum/?hl=en#!topic/django-users/zwMWNdIqB3A.

Please take a look.

Jianbao

Reply all
Reply to author
Forward
0 new messages