When combining unicode and non-unicode MySQL connections, each instance is affected by the other one. Depending on which instance used last.
This is due to the fact that some items of the conversions list are references instead of independent objects (e.g. conv[FIELD_TYPE.BLOB]).
Furthermore it is possible to patch just one file of the ZMySQLDA package to get unicode support instead of four files.
To get this working, you have to modify only two functions of db.py
Now you can turn on unicode support by adding the string "use_unicode" to the end(!) of the connection string.
def _parse_connection_string(self, connection):
kwargs = {'conv': self.conv.copy()}
items = split(connection)
if not items: return kwargs
if items[-1] == 'use_unicode':
self.use_unicode = True
del items[-1]
# Update the converters on the unicode object
def u(s):
return s.decode('UTF8')
kwargs['conv'][FIELD_TYPE.STRING] = u
kwargs['conv'][FIELD_TYPE.VAR_STRING] = u
kwargs['conv'][FIELD_TYPE.BLOB] = self.conv[FIELD_TYPE.BLOB][:]
kwargs['conv'][FIELD_TYPE.BLOB].insert(-1, (None, u))
else:
self.use_unicode = False
# Reset these elements - by default they should not be present
if self.conv.has_key(FIELD_TYPE.STRING):
kwargs['conv'][FIELD_TYPE.STRING] = self.conv[FIELD_TYPE.STRING]
elif kwargs['conv'].has_key(FIELD_TYPE.STRING):
del kwargs['conv'][FIELD_TYPE.STRING]
if self.conv.has_key(FIELD_TYPE.VAR_STRING):
kwargs['conv'][FIELD_TYPE.VAR_STRING] = self.conv[FIELD_TYPE.VAR_STRING]
elif kwargs['conv'].has_key(FIELD_TYPE.VAR_STRING):
del kwargs['conv'][FIELD_TYPE.VAR_STRING]
if self.conv.has_key(FIELD_TYPE.BLOB):
kwargs['conv'][FIELD_TYPE.BLOB] = self.conv[FIELD_TYPE.BLOB]
elif kwargs['conv'].has_key(FIELD_TYPE.BLOB):
del kwargs['conv'][FIELD_TYPE.BLOB]
db_host, items = items[0], items[1:]
if '@' in db_host:
db, host = split(db_host,'@',1)
kwargs['db'] = db
if ':' in host:
host, port = split(host,':',1)
kwargs['port'] = int(port)
kwargs['host'] = host
else:
kwargs['db'] = db_host
if kwargs['db'][0] in ('+', '-'):
self._try_transactions = kwargs['db'][0]
kwargs['db'] = kwargs['db'][1:]
else:
self._try_transactions = None
if not items: return kwargs
kwargs['user'], items = items[0], items[1:]
if not items: return kwargs
kwargs['passwd'], items = items[0], items[1:]
if not items: return kwargs
kwargs['unix_socket'], items = items[0], items[1:]
return kwargs
def string_literal(self, s):
if self.use_unicode and type(s) == unicode:
s = s.encode('UTF8')
return self.db.string_literal(s)
db.py from the ZMySQLDA product
Logged In: YES
user_id=1115795
Originator: YES
<pre>
def _parse_connection_string(self, connection):
kwargs = {'conv': self.conv.copy()}
items = split(connection)
if not items: return kwargs
if items[-1] == 'use_unicode':
self.use_unicode = True
del items[-1]
# Update the converters on the unicode object
def u(s):
return s.decode('UTF8')
kwargs['conv'][FIELD_TYPE.STRING] = u
kwargs['conv'][FIELD_TYPE.VAR_STRING] = u
kwargs['conv'][FIELD_TYPE.BLOB] = self.conv[FIELD_TYPE.BLOB][:]
kwargs['conv'][FIELD_TYPE.BLOB].insert(-1, (None, u))
else:
self.use_unicode = False
# Reset these elements - by default they should not be present
if self.conv.has_key(FIELD_TYPE.STRING):
kwargs['conv'][FIELD_TYPE.STRING] = self.conv[FIELD_TYPE.STRING]
elif kwargs['conv'].has_key(FIELD_TYPE.STRING):
del kwargs['conv'][FIELD_TYPE.STRING]
if self.conv.has_key(FIELD_TYPE.VAR_STRING):
kwargs['conv'][FIELD_TYPE.VAR_STRING] = self.conv[FIELD_TYPE.VAR_STRING]
elif kwargs['conv'].has_key(FIELD_TYPE.VAR_STRING):
del kwargs['conv'][FIELD_TYPE.VAR_STRING]
if self.conv.has_key(FIELD_TYPE.BLOB):
kwargs['conv'][FIELD_TYPE.BLOB] = self.conv[FIELD_TYPE.BLOB]
elif kwargs['conv'].has_key(FIELD_TYPE.BLOB):
del kwargs['conv'][FIELD_TYPE.BLOB]
db_host, items = items[0], items[1:]
if '@' in db_host:
db, host = split(db_host,'@',1)
kwargs['db'] = db
if ':' in host:
host, port = split(host,':',1)
kwargs['port'] = int(port)
kwargs['host'] = host
else:
kwargs['db'] = db_host
if kwargs['db'][0] in ('+', '-'):
self._try_transactions = kwargs['db'][0]
kwargs['db'] = kwargs['db'][1:]
else:
self._try_transactions = None
if not items: return kwargs
kwargs['user'], items = items[0], items[1:]
if not items: return kwargs
kwargs['passwd'], items = items[0], items[1:]
if not items: return kwargs
kwargs['unix_socket'], items = items[0], items[1:]
return kwargs
def string_literal(self, s):
if self.use_unicode and type(s) == unicode:
s = s.encode('UTF8')
return self.db.string_literal(s)
</pre>