#5246: MS SQL Server backend using pyodbc.
-------------------------------------------------------------+--------------
Reporter: Filip Wasilewski <
filip.wa...@gmail.com> | Owner: adrian
Status: new | Component: Database wrapper
Version: SVN | Resolution:
Keywords: mssql pyodbc database backend | Stage: Unreviewed
Has_patch: 1 | Needs_docs: 0
Needs_tests: 0 | Needs_better_patch: 0
-------------------------------------------------------------+--------------
Comment (by Filip Wasilewski <
filip.wa...@gmail.com>):
Thanks for pointing this out. This error is a known issue when working
with MSSQL 2000, although I didn't spot that it occurs in the admin
interface.
The data type used to store `TextField`s in SQL Server 2000 is `ntext`. On
the other hand Python Unicode strings are passed to SQL Server via pyodbc
as `nvarchar`s. The problem is when someone tries to compare this two
different data types for equality with the "`=`" operator. The following
will raise an error in MSSQL 2000 and 2005:
{{{
#!sql
SELECT 1 WHERE cast('a' as ntext) = N'a'
}}}
In SQL Server 2005 there is a new `[n]varchar(max)` data type which does
not have such limitations:
{{{
#!sql
SELECT 1 WHERE cast('a' as nvarchar(max)) = N'a'
}}}
and we can use that for `TextField`s. Also, according to the MSDN, the
`[n]text` type is going to be removed in future versions of MSSQL.
There are several possible ways to solve this for MSSQL 2000:
1. Use a specific `__exact` operator for `TextField`.[[BR]]
The exact matching is translated into "`= %s`", where "`%s`" is
parameter placeholder (see operators in `DatabaseWrapper`). For the
`TextField` it would need to be translated into "`LIKE %s`" statement or
use explicit casting of parameter to `ntext` type - "`= cast(%s as
ntext)`".
This approach would require patching the `get_where_clause` function
in `django\db\models\query.py`, which I would prefer to avoid.[[BR]][[BR]]
1. Change the django admin model for `LogEntry`.[[BR]]
I'm not sure about that, but maybe we don't need `object_id`s longer
than 255 characters and could change the model a bit from:
{{{
#!python
class LogEntry(models.Model):
...
object_id = models.TextField(_('object id'), blank=True,
null=True)
...
}}}
to something like:
{{{
#!python
class LogEntry(models.Model):
...
object_id = models.CharField(_('object id'), blank=True,
null=True, max_length=255)
...
}}}
Personally, I would incline to the second option as there is already quite
a lot of backend-specific conditional statements in the `django.db`, but
would like to hear how this may influence the admin interface
functionality and how would work with other backends first.
'''Note:''' Regarding to the versions of the patch listed on this site,
the highest number is the most recent patch version (currently
mssql_pyodbc.2.patch) and previous versions should not be used. I don't
have rights to replace or remove the older attachments and they are simply
listed here as a ticket history.
--
Ticket URL: <
http://code.djangoproject.com/ticket/5246#comment:5>