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.

Reply via email to