Opened 18 years ago
Closed 16 years ago
#3642 closed (wontfix)
[multi-db] Filters with nested foreign keys across databases fail
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | other branch |
Severity: | Keywords: | multi-db | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
If you have two or more databases:
DATABASE_ENGINE = 'mysql' # 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
DATABASE_NAME = 'djangodb' # Or path to database file if using sqlite3.
DATABASE_USER = 'root' # Not used with sqlite3.
DATABASE_PASSWORD = # Not used with sqlite3.
DATABASE_HOST = 'somehost' # Set to empty string for localhost. Not used with sqlite3.
DATABASE_PORT = # Set to empty string for default. Not used with sqlite3.
OTHER_DATABASES = {
'mortgagedb': {
'DATABASE_NAME': 'mortgagedb',
'DATABASE_USER': 'root',
'DATABASE_PASSWORD': ,
'MODELS': mortgagedb
},
'userdb': {
'DATABASE_NAME': 'userdb',
'DATABASE_USER': 'root',
'DATABASE_PASSWORD': ,
'MODELS': userdb
},
.
.
.
Then you have models that look like this:
Users Model:
class Company(models.Model):
company_id = models.AutoField(primary_key=True)
company_name = models.CharField(blank=True, maxlength=150)
....other properties
class UserInfo(models.Model):
user_id = models.AutoField(primary_key=True)
login = models.CharField(blank=True, maxlength=765)
first_name = models.CharField(blank=True, maxlength=60)
middle_name = models.CharField(blank=True, maxlength=60)
last_name = models.CharField(blank=True, maxlength=60)
company = models.ForeignKey(Company,related_name="company_users")
Loans Model:
(import users model up top)
class Mortgage(models.Model):
mortgage_id = models.AutoField(primary_key=True)
property = models.ForeignKey(Property)
obligor_user = models.ForeignKey(UserInfo, null=True)
Then in the views if you try to do this:
paramsnew = {}
paramsnewobligor_user__company__company_name= request.POSTcompany_name # istartswith fails too, as well as trying to do company ids with in
mortgages = Mortgage.objects.filter(params).distinct() #Mortgage.objects.filter(params) fails too
You get the following error:
Exception Value: (1146, "Table 'mortgagedb.user_info' doesn't exist")
Exception Location: /usr/lib/python2.4/site-packages/MySQLdb/connections.py in defaulterrorhandler, line 33
Traceback (innermost last)
Switch to copy-and-paste view
- /usr/lib/python2.4/site-packages/Django-0.95-py2.4.egg/django/core/handlers/base.py in get_response
- # Apply view middleware
- for middleware_method in self._view_middleware:
- response = middleware_method(request, callback, callback_args, callback_kwargs)
- if response:
- return response 72.
- try:
- response = callback(request, *callback_args, callback_kwargs) ...
- except Exception, e:
- # If the view raised an exception, run it through exception
- # middleware, and if the exception middleware returns a
- # response, use that. Otherwise, reraise the exception.
- for middleware_method in self._exception_middleware:
- response = middleware_method(request, e)
~': ':~', 'HTTP_~': '', 'PATH_INFO': '/mortgageadmin/', 'PATH_TRANSLATED': None, 'QUERY_STRING': None, 'REMOTE_ADDR': '192.168.1.111', 'REMOTE_HOST': None, 'REMOTE_IDENT': None, 'REMOTE_USER': None, 'REQUEST_METHOD': 'POST', 'SCRIPT_NAME': None, 'SERVER_NAME': 'rssws1d.realdatacenter.com', 'SERVER_PORT': 0, 'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_SOFTWARE': 'mod_python'}> resolver <django.core.urlresolvers.RegexURLResolver object at 0xb705c7ec> response None self <django.core.handlers.modpython.ModPythonHandler object at 0xb724dfcc> settings <django.conf.LazySettings object at 0xb7202acc> urlresolvers <module 'django.core.urlresolvers' from '/usr/lib/python2.4/site-packages/Django-0.95-py2.4.egg/django/core/urlresolvers.pyc'> - /home/carole/rssproject/rsswww/views/mortgages.py in rendermortgageadmin
- paramsappraiser_user__user_id = current_user.user_id 130.
- # do they need to filter the list further?
- count = 0
- if request.session.get("SortMortgageListBy"):
- count = Mortgage.objects.filter(params).order_by(request.session.get("SortMortgageListBy")).distinct().count()
- else:
- count = Mortgage.objects.filter(params).distinct().count() ... 137.
- if count > 300:
- specialtitle="View A Filtered List Of Mortgages:"
- # we want to have them filter the list down some..this number is too much to look at anyway
- return render_to_response('mortgageadmin.html',{'mortgagecount':count,'displayfilter':"yes",'specialtitle':specialtitle,'current_role':current_role,'company_name':company_name,'city':city,'state':state,'zip':zip,'menu':menu},context_instance=RequestContext(request))
- else:
~': ':~', 'HTTP_~': '', 'PATH_INFO': '/mortgageadmin/', 'PATH_TRANSLATED': None, 'QUERY_STRING': None, 'REMOTE_ADDR': '192.168.1.111', 'REMOTE_HOST': None, 'REMOTE_IDENT': None, 'REMOTE_USER': None, 'REQUEST_METHOD': 'POST', 'SCRIPT_NAME': None, 'SERVER_NAME': 'rssws1d.realdatacenter.com', 'SERVER_PORT': 0, 'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_SOFTWARE': 'mod_python'}> sort specialtitle 'Your Current Mortgages' state zip - /usr/lib/python2.4/site-packages/Django-0.95-py2.4.egg/django/db/models/query.py in count
- counter._limit = None
- counter._select_related = False
- select, sql, params = counter._get_sql_clause()
- cursor = connection.cursor()
- if self._distinct:
- id_col = "%s.%s" % (backend.quote_name(self.model._meta.db_table),
- backend.quote_name(self.model._meta.pk.column))
- cursor.execute("SELECT COUNT(DISTINCT(%s))" % id_col + sql, params) ...
- else:
- cursor.execute("SELECT COUNT(*)" + sql, params)
- return cursor.fetchone()[0] 206.
- def get(self, *args, kwargs):
- "Performs the SELECT and returns a single object matching the given keyword arguments."
mortgage
.mortgage_id
' params ['Trinity', 50001L] select ['mortgage
.mortgage_id
', 'mortgage
.property_id
', 'mortgage
.user_id
', 'mortgage
.credit_score
', 'mortgage
.ltarv
', 'mortgage
.ltv_current
', 'mortgage
.ltv_after
', 'mortgage
.mortgage_amount
', 'mortgage
.estimated_months
', 'mortgage
.obligor_user_id
', 'mortgage
.obligor_company_id
', 'mortgage
.receiver_company_id
', 'mortgage
.closing_agent_user_id
', 'mortgage
.closing_agent_company_id
', 'mortgage
.mortgage_broker_user_id
', 'mortgage
.mortgage_broker_company_id
', 'mortgage
.title_company_id
', 'mortgage
.title_company_user_id
', 'mortgage
.assignment_date
', 'mortgage
.letter_date
', 'mortgage
.origination_date
', 'mortgage
.cancellation_date
', 'mortgage
.fail_to_close_date
', 'mortgage
.mature_date
', 'mortgage
.payoff_date
', 'mortgage
.completion_date
', 'mortgage
.life_of_loan
', 'mortgage
.originator_user_id
', 'mortgage
.originator_company_id
', 'mortgage
.escrow
', 'mortgage
.loan_amount
', 'mortgage
.payoff_amount
', 'mortgage
.appraisal
', 'mortgage
.loan_to_value
', 'mortgage
.points
', 'mortgage
.points_dollars
', 'mortgage
.interest_rate
', 'mortgage
.interest_amount
', 'mortgage
.cost_of_credit_yearly_rate
', 'mortgage
.finance_charge
', 'mortgage
.number_of_payments
', 'mortgage
.total_payments
', 'mortgage
.daily_interest
', 'mortgage
.days_of_interest
', 'mortgage
.deferred_interest
', 'mortgage
.total_interest
', 'mortgage
.due_date
', 'mortgage
.first_payment_month_year
', 'mortgage
.last_payment_month_year
', 'mortgage
.update_user_id
', 'mortgage
.address_id
', 'mortgage
.time_stamp
'] self Error in formatting:(1146, "Table 'mortgagedb.user_info' doesn't exist") sql ' FROMmortgage
INNER JOINuser_info
ASmortgage__obligor_user
ONmortgage
.obligor_user_id
=mortgage__obligor_user
.user_id
INNER JOINcompany
ASmortgage__obligor_user__company
ONmortgage__obligor_user
.company_id
=mortgage__obligor_user__company
.company_id
WHERE (mortgage__obligor_user__company
.company_name
= %s ANDmortgage
.originator_user_id
= %s)' - /usr/lib/python2.4/site-packages/Django-0.95-py2.4.egg/django/db/backends/util.py in execute
- def init(self, cursor, db):
- self.cursor = cursor
- self.db = db 8.
- def execute(self, sql, params=()):
- start = time()
- try:
- return self.cursor.execute(sql, params) ...
- finally:
- stop = time()
- # If params was a list, convert it to a tuple, because string
- # formatting with '%' only works with tuples or dicts.
- if not isinstance(params, (tuple, dict)):
- params = tuple(params)
▶ Local vars
Variable Value
params
('Trinity', 50001L)
self
<django.db.backends.util.CursorDebugWrapper object at 0xb6c85cac>
sql
'SELECT COUNT(DISTINCT(mortgage
.mortgage_id
)) FROMmortgage
INNER JOINuser_info
ASmortgage__obligor_user
ONmortgage
.obligor_user_id
=mortgage__obligor_user
.user_id
INNER JOINcompany
ASmortgage__obligor_user__company
ONmortgage__obligor_user
.company_id
=mortgage__obligor_user__company
.company_id
WHERE (mortgage__obligor_user__company
.company_name
= %s ANDmortgage
.originator_user_id
= %s)'
start
1172897283.3177619
stop
1172897283.3196101
- /usr/lib/python2.4/site-packages/Django-0.95-py2.4.egg/django/db/backends/mysql/base.py in execute
- # It's only used when DEBUG=True.
- class MysqlDebugWrapper:
- def init(self, cursor):
- self.cursor = cursor 32.
- def execute(self, sql, params=()):
- try:
- return self.cursor.execute(sql, params) ...
- except Database.Warning, w:
- self.cursor.execute("SHOW WARNINGS")
- raise Database.Warning, "%s: %s" % (w, self.cursor.fetchall()) 39.
- def executemany(self, sql, param_list):
- try:
mortgage
.mortgage_id
)) FROMmortgage
INNER JOINuser_info
ASmortgage__obligor_user
ONmortgage
.obligor_user_id
=mortgage__obligor_user
.user_id
INNER JOINcompany
ASmortgage__obligor_user__company
ONmortgage__obligor_user
.company_id
=mortgage__obligor_user__company
.company_id
WHERE (mortgage__obligor_user__company
.company_name
= %s ANDmortgage
.originator_user_id
= %s)' - /usr/lib/python2.4/site-packages/MySQLdb/cursors.py in execute
- else:
- self.messages.append((TypeError, m))
- self.errorhandler(self, TypeError, m)
- except:
- exc, value, tb = exc_info()
- del tb
- self.messages.append((exc, value))
- self.errorhandler(self, exc, value) ...
- self._executed = query
- self._warning_check()
- return r 141.
- def executemany(self, query, args):
143.
▶ Local vars
Variable Value
ListType
<type 'list'>
TupleType
<type 'tuple'>
args
['Trinity', 50001L]
exc
<class _mysql_exceptions.ProgrammingError at 0xb6d3cbfc>
exc_info
<built-in function exc_info>
query
'SELECT COUNT(DISTINCT(mortgage
.mortgage_id
)) FROMmortgage
INNER JOINuser_info
ASmortgage__obligor_user
ONmortgage
.obligor_user_id
=mortgage__obligor_user
.user_id
INNER JOINcompany
ASmortgage__obligor_user__company
ONmortgage__obligor_user
.company_id
=mortgage__obligor_user__company
.company_id
WHERE (mortgage__obligor_user__company
.company_name
= %s ANDmortgage
.originator_user_id
= %s)'
self
<MySQLdb.cursors.Cursor object at 0xb6c85a2c>
value
<_mysql_exceptions.ProgrammingError instance at 0xb6c85f4c>
- /usr/lib/python2.4/site-packages/MySQLdb/connections.py in defaulterrorhandler
26.
- """
- error = errorclass, errorvalue
- if cursor:
- cursor.messages.append(error)
- else:
- connection.messages.append(error)
- raise errorclass, errorvalue ... 34. 35.
- class Connection(_mysql.connection): 37.
- """MySQL Database Connection Object"""
39.
▶ Local vars
Change History (5)
comment:1 by , 18 years ago
Summary: | [multip-db] Filters with nested foreign keys across databases fail → [multi-db] Filters with nested foreign keys across databases fail |
---|
comment:2 by , 18 years ago
comment:3 by , 18 years ago
Keywords: | multi-db added |
---|---|
Triage Stage: | Unreviewed → Accepted |
Version: | SVN → other branch |
comment:4 by , 18 years ago
This sounds exactly like the issue I had, it's to do with the select clause being in one SQL dialect and some other stuff being in another (sorry for being vague I don't have the details to hand). Ticket 3885 has some more detail with some preliminary findings into causes.
comment:5 by , 16 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
The multi-db is no longer active. Alternative approaches are being considered for trunk.
Sorry... I haven't pasted a code block in here before...let me do that the correct way...I'll preview from now on ;)
Settings file:
Models Code:
View Code