Code

Opened 5 years ago

Closed 5 years ago

#11169 closed (duplicate)

django.db.models.sql.where is using the global "connection" rather than the query object's "connection"

Reported by: crcradock Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Keywords:
Cc: 10454 Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description (last modified by Alex)

I have need to use both MySQL database and an MS SQL server (via ODBC). I noticed some rather strange quirks which lead me to work out that django.db.models.sql.where is referring to the global "connection" rather than the query's connection. Primarily queries to the other database type appear to fail with incorrect "where" clauses.

Viz: assume MySQL is the default database as quoted in the project's settings.py file

>>> import MSSQL.model
>>> MSSQL.model.RandomTable.get(field__startswith='ticket')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/lib/python2.5/site-packages/django/db/models/manager.py", line 120, in get
    return self.get_query_set().get(*args, **kwargs)
  File "/usr/lib/python2.5/site-packages/django/db/models/query.py", line 269, in get
    num = len(clone)
  File "/usr/lib/python2.5/site-packages/django/db/models/query.py", line 68, in __len__
    self._result_cache = list(self.iterator())
  File "/usr/lib/python2.5/site-packages/django/db/models/query.py", line 207, in iterator
    for row in self.query.results_iter():
  File "/usr/lib/python2.5/site-packages/django/db/models/sql/query.py", line 262, in results_iter
    for rows in self.execute_sql(MULTI):
  File "/usr/lib/python2.5/site-packages/django/db/models/sql/query.py", line 2294, in execute_sql
    cursor.execute(sql, params)
  File "/usr/lib/python2.5/site-packages/django/db/backends/util.py", line 19, in execute
    return self.cursor.execute(sql, params)
  File "/usr/lib/python2.5/site-packages/django/db/backends/py_odbc/base.py", line 226, in execute
    return self.cursor.execute(sql, params)
ProgrammingError: ('42000', '[42000] [FreeTDS][SQL Server]Statement(s) could not be prepared. (8180) (SQLPrepare)')

Does anyone know how to find the correct connection in the "as_sql" subroutine in django.db.models.sql.where, or do we need to call django.db.models.sql.where.as_sql with the appropriate "connection" as a parameter?

Affected lines:

156:            cast_sql = connection.ops.datetime_cast_sql()
166:        if lookup_type in connection.operators:
167:            format = "%s %%s %%s" % (connection.ops.lookup_cast(lookup_type),)
169:                              connection.operators[lookup_type] % cast_sql,
182:            return ('%s = %%s' % connection.ops.date_extract_sql(lookup_type, field_sql),
188:            return (connection.ops.fulltext_search_sql(field_sql), params)
190:            return connection.ops.regex_lookup(lookup_type) % (field_sql, cast_sql), params
205:        return connection.ops.field_cast_sql(db_type) % lhs

Just incase it has a bearing on the matter I'm using a DB-Manager for the tables of the form:

class ODBCManager(models.Manager):
    use_for_related_fields = True
    cached_connection = False
    query = False

    def get_query_set(self):
        if( not self.cached_connection ):
          h_connection=py_odbc.base.DatabaseWrapper( dict(
                DATABASE_ODBC_DSN=settings.DATABASE_ODBC_DSN
               ,DATABASE_NAME=settings.DATABASE_ODBC_DATABASE
               ,DATABASE_OPTIONS=dict()
          ) )
          h_query = h_connection.ops.query_class(sql.query.BaseQuery)
          self.query = h_query(self.model, h_connection )
          self.cached_connection = True
        return QuerySet(self.model,self.query)

Attachments (0)

Change History (2)

comment:1 Changed 5 years ago by Alex

  • Description modified (diff)
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

Fixed formatting.

comment:2 Changed 5 years ago by Alex

  • Resolution set to duplicate
  • Status changed from new to closed

Marking as a dupe of #1142. It's not a literal dupe, but this work is happening as a part of the google summer of code multi-db work.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.