#17863: Storing user and user profile in different databases?
-----------------------------------------------+--------------------
     Reporter:  Henning Kage <henning.kage@…>  |      Owner:  nobody
         Type:  Bug                            |     Status:  new
    Component:  contrib.auth                   |    Version:  SVN
     Severity:  Normal                         |   Keywords:
 Triage Stage:  Unreviewed                     |  Has patch:  1
Easy pickings:  0                              |      UI/UX:  0
-----------------------------------------------+--------------------
 I am not sure, if this is a possible bug or a wanted feature. I want to
 outsource all tables from a Django application in a separate database.
 This includes the user profile, that I want to be stored in the app's own
 database. I am using the following minimal project, to reproduce the
 traceback:

 '''settings.py'''

 {{{
 DATABASES = {
     'default': {
         'ENGINE': 'django.db.backends.sqlite3',
         'NAME': 'default.db',
     },
     'app': {
         'ENGINE': 'django.db.backends.sqlite3',
         'NAME': 'app.db',
     }

 }
 DATABASE_ROUTERS = ['app.router.Router']
 INSTALLED_APPS = [
   # ...
   'app',
   ]
 AUTH_PROFILE_MODULE = 'app.UserProfile'
 }}}

 '''app/models.py'''

 {{{
 #!python
 from django.contrib.auth.models import User
 from django.db import models

 class UserProfile(models.Model):

     user = models.ForeignKey(User)
 }}}

 '''app/router.py'''

 {{{
 #!python
 # -*- coding: utf-8 -*-

 class Router(object):

     def db_for_read(self, model, **hints):
         if model._meta.app_label == 'app':
             return 'app'
         return None

     def db_for_write(self, model, **hints):
         if model._meta.app_label == 'app':
             return 'app'
         return None

     def allow_relation(self, obj1, obj2, **hints):
         if (obj1._meta.app_label == 'app'
             or obj2._meta.app_label == 'app'):
             return True
         return None

     def allow_syncdb(self, db, model):
         if db == 'app':
             return model._meta.app_label == 'app'
         elif model._meta.app_label == 'app':
             return False
         return None
 }}}

 '''app/tests.py'''

 {{{
 #!python
 from django.contrib.auth.models import User
 from django.test import TestCase

 from app.models import UserProfile

 class SimpleTest(TestCase):

     def test_userprofile(self):
         u = User()
         u.save()
         p = UserProfile()
         p.user = u
         p.save()
         u.get_profile()
 }}}

 Although it is possible to specify a custom user profile class, Django
 always assumes, that the user profile model is saved in the same database
 Django stores the auth_user table. The unittest will result in the
 following traceback by calling the user's profile with `User.get_profile`:

 {{{
 Traceback (most recent call last):
   File "/Users/henningkage/Projekte/sandbox/userprofile/app/tests.py",
 line 14, in test_userprofile
     u.get_profile()
   File
 
"/Users/henningkage/Python/django_multi_db/src/django/django/contrib/auth/models.py",
 line 401, in get_profile
     self._state.db).get(user__id__exact=self.id)
   File
 
"/Users/henningkage/Python/django_multi_db/src/django/django/db/models/query.py",
 line 361, in get
     num = len(clone)
   File
 
"/Users/henningkage/Python/django_multi_db/src/django/django/db/models/query.py",
 line 85, in __len__
     self._result_cache = list(self.iterator())
   File
 
"/Users/henningkage/Python/django_multi_db/src/django/django/db/models/query.py",
 line 291, in iterator
     for row in compiler.results_iter():
   File
 
"/Users/henningkage/Python/django_multi_db/src/django/django/db/models/sql/compiler.py",
 line 763, in results_iter
     for rows in self.execute_sql(MULTI):
   File
 
"/Users/henningkage/Python/django_multi_db/src/django/django/db/models/sql/compiler.py",
 line 818, in execute_sql
     cursor.execute(sql, params)
   File
 
"/Users/henningkage/Python/django_multi_db/src/django/django/db/backends/sqlite3/base.py",
 line 337, in execute
     return Database.Cursor.execute(self, query, params)
 DatabaseError: no such table: app_userprofile
 }}}

 Does Django needs the user and user profile model in the same database as
 foreign keys across multiple databases are not possible? My attached
 (minmal) change will return a valid user profile model instance. The only
 disadvantage to me is the fact, that the user profile has no real relation
 to the user and will only return the user's id. This would be the normal
 behaviour for relationships across multiple databases. But it would be
 possible to store the user profile in a different database than Django's
 internal tables. If this topic has already been discussed and I missed it,
 sorry for the ticket.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/17863>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

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

Reply via email to