Package: python-sqlalchemy
Version: 0.4.7p1-2
Severity: important
trying to save Unicode strings with the sqlite backend fails with
this error:
raise exceptions.DBAPIError.instance(statement, parameters, e,
connection_invalidated=is_disconnect)
sqlalchemy.exceptions.ProgrammingError: (ProgrammingError) You must not
use 8-bit bytestrings unless you use a text_factory that can interpret
8-bit bytestrings (like text_factory = str). It is highly recommended
that you instead just switch your application to Unicode strings.
according to sqlalchemy developers, this is related to an
unannounced change in sqlite. this has been fixed in sqlalchemy's trunk,
revision 5158. I ported the change to 0.4.7p1. attached is the patch.
-- System Information:
Debian Release: lenny/sid
APT prefers unstable
APT policy: (500, 'unstable')
Architecture: i386 (i686)
Kernel: Linux 2.6.26-1-686 (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Versions of packages python-sqlalchemy depends on:
ii python 2.5.2-2 An interactive high-level object-o
ii python-support 0.8.6 automated rebuilding support for P
python-sqlalchemy recommends no packages.
Versions of packages python-sqlalchemy suggests:
ii python 2.5.2-2 An interactive high-level object-o
pn python-kinterbasdb <none> (no description available)
ii python-mysqldb 1.2.2-7 A Python interface to MySQL
pn python-psycopg2 <none> (no description available)
ii python-pysqlite1.1 1.1.8a-3 python interface to SQLite 3
ii python-pysqlite2 2.5.0-1 Python interface to SQLite 3
ii python-sqlalchemy-doc 0.4.7p1-2 Documentation for the SQLAlchemy P
-- no debconf information
Index: /test/dialect/sqlite.py
===================================================================
--- /test/dialect/sqlite.py (revision 5121)
+++ /test/dialect/sqlite.py (revision 5158)
@@ -29,4 +29,22 @@
self.assertEquals(bp(dt), '2008-06-27 12:00:00.125')
self.assertEquals(rp(bp(dt)), dt)
+
+ def test_no_convert_unicode(self):
+ """test no utf-8 encoding occurs"""
+
+ dialect = sqlite.dialect()
+ for t in (
+ String(convert_unicode=True),
+ CHAR(convert_unicode=True),
+ Unicode(),
+ UnicodeText(),
+ String(assert_unicode=True, convert_unicode=True),
+ CHAR(assert_unicode=True, convert_unicode=True),
+ Unicode(assert_unicode=True),
+ UnicodeText(assert_unicode=True)
+ ):
+
+ bindproc = t.dialect_impl(dialect).bind_processor(dialect)
+ assert not bindproc or isinstance(bindproc(u"some string"), unicode)
@testing.uses_deprecated('Using String type with no length')
Index: /lib/sqlalchemy/databases/sqlite.py
===================================================================
--- /lib/sqlalchemy/databases/sqlite.py (revision 5122)
+++ /lib/sqlalchemy/databases/sqlite.py (revision 5158)
@@ -127,13 +127,41 @@
return process
-class SLText(sqltypes.Text):
+class SLUnicodeMixin(object):
+ def bind_processor(self, dialect):
+ if self.convert_unicode or dialect.convert_unicode:
+ if self.assert_unicode is None:
+ assert_unicode = dialect.assert_unicode
+ else:
+ assert_unicode = self.assert_unicode
+
+ if not assert_unicode:
+ return None
+
+ def process(value):
+ if not isinstance(value, (unicode, NoneType)):
+ if assert_unicode == 'warn':
+ util.warn("Unicode type received non-unicode bind "
+ "param value %r" % value)
+ return value
+ else:
+ raise exc.InvalidRequestError("Unicode type received non-unicode bind param value %r" % value)
+ else:
+ return value
+ return process
+ else:
+ return None
+
+ def result_processor(self, dialect):
+ return None
+
+class SLText(SLUnicodeMixin, sqltypes.Text):
def get_col_spec(self):
return "TEXT"
-class SLString(sqltypes.String):
+class SLString(SLUnicodeMixin, sqltypes.String):
def get_col_spec(self):
return "VARCHAR(%(length)s)" % {'length' : self.length}
-class SLChar(sqltypes.CHAR):
+class SLChar(SLUnicodeMixin, sqltypes.CHAR):
def get_col_spec(self):
return "CHAR(%(length)s)" % {'length' : self.length}
Index: /CHANGES
===================================================================
--- /CHANGES (revision 5150)
+++ /CHANGES (revision 5158)
@@ -72,4 +72,10 @@
dates with microseconds. [ticket:968]
+ - String's (and Unicode's, UnicodeText's, etc.) convert_unicode
+ logic disabled in the sqlite dialect, to adjust for pysqlite
+ 2.5.0's new requirement that only Python unicode objects are
+ accepted;
+ http://itsystementwicklung.de/pipermail/list-pysqlite/2008-March/000018.html
+
- mysql
- Temporary tables are now reflectable.