represented so far but will continue to add to the system [ticket:615]
- added new flag to String and create_engine(),
- assert_unicode=(True|False|None). Defaults to `False` or `None` on
- create_engine() and String, `True` on the Unicode type. When `True`,
+ assert_unicode=(True|False|'warn'|None). Defaults to `False` or `None` on
+ create_engine() and String, `'warn'` on the Unicode type. When `True`,
results in all unicode conversion operations raising an exception when a
- non-unicode bytestring is passed as a bind parameter. It is strongly
- advised that all unicode-aware applications make proper use of Python
- unicode objects (i.e. u'hello' and not 'hello').
+ non-unicode bytestring is passed as a bind parameter. 'warn' results
+ in a warning. It is strongly advised that all unicode-aware applications
+ make proper use of Python unicode objects (i.e. u'hello' and not 'hello')
+ so that data round trips accurately.
- tables with schemas can still be used in sqlite, firebird,
schema name just gets dropped [ticket:890]
`convert_unicode=True` indicates that incoming strings, if they are Python `unicode` strings, will be encoded into a raw bytestring using the `encoding` attribute of the dialect (defaults to `utf-8`). Similarly, raw bytestrings coming back from the database will be decoded into `unicode` objects on the way back.
-`assert_unicode` is set to `None` by default. When `True`, it indicates that incoming bind parameters will be checked that they are in fact `unicode` objects, else an error is raised. Setting it to `None` indicates that the dialect-level `convert_unicode` setting should take place, whereas setting it to `False` disables it unconditionally (this flag is new as of version 0.4.2).
+`assert_unicode` is set to `None` by default. When `True`, it indicates that incoming bind parameters will be checked that they are in fact `unicode` objects, else an error is raised. A value of `'warn'` instead raises a warning. Setting it to `None` indicates that the dialect-level `convert_unicode` setting should take place, whereas setting it to `False` disables it unconditionally (this flag is new as of version 0.4.2).
Both `convert_unicode` and `assert_unicode` may be set at the engine level as flags to `create_engine()`.
#### Unicode
-The `Unicode` type is shorthand for `String` with `convert_unicode=True` and `assert_unicode=True`. When writing a unicode-aware appication, it is strongly recommended that this type is used, and that only unicode strings are used in the application. By "unicode string" we mean a string with a u, i.e. `u'hello'`. Otherwise, particularly when using the ORM, data will be converted to unicode when it returns from the database, but local data which was generated locally will not be in unicode format, which can create confusion.
+The `Unicode` type is shorthand for `String` with `convert_unicode=True` and `assert_unicode='warn'`. When writing a unicode-aware appication, it is strongly recommended that this type is used, and that only unicode strings are used in the application. By "unicode string" we mean a string with a u, i.e. `u'hello'`. Otherwise, particularly when using the ORM, data will be converted to unicode when it returns from the database, but local data which was generated locally will not be in unicode format, which can create confusion.
#### Numeric
import inspect
import datetime as dt
+import warnings
from sqlalchemy import exceptions
from sqlalchemy.util import pickle, Decimal as _python_Decimal
def bind_processor(self, dialect):
if self.convert_unicode or dialect.convert_unicode:
if self.assert_unicode is None:
- assert_unicode = bool(dialect.assert_unicode)
+ assert_unicode = dialect.assert_unicode
else:
assert_unicode = self.assert_unicode
def process(value):
if isinstance(value, unicode):
return value.encode(dialect.encoding)
elif assert_unicode and not isinstance(value, (unicode, NoneType)):
- raise exceptions.InvalidRequestError("Received non-unicode bind param value %r" % value)
+ if assert_unicode == 'warn':
+ warnings.warn(RuntimeWarning("Unicode type received non-unicode bind param value %r" % value))
+ else:
+ raise exceptions.InvalidRequestError("Unicode type received non-unicode bind param value %r" % value)
else:
return value
return process
class Unicode(String):
def __init__(self, length=None, **kwargs):
- kwargs['convert_unicode'] = kwargs['assert_unicode'] = True
+ kwargs['convert_unicode'] = True
+ kwargs['assert_unicode'] = 'warn'
super(Unicode, self).__init__(length=length, **kwargs)
class Integer(TypeEngine):
self.assert_(not isinstance(x['plain_varchar'], unicode) and x['plain_varchar'] == rawdata)
def testassert(self):
+ import warnings
+ warnings.filterwarnings("error", r".*non-unicode bind")
+
try:
unicode_table.insert().execute(unicode_varchar='im not unicode')
assert False
- except exceptions.InvalidRequestError, e:
- assert str(e) == "Received non-unicode bind param value 'im not unicode'"
+ except RuntimeWarning, e:
+ assert str(e) == "Unicode type received non-unicode bind param value 'im not unicode'", str(e)
unicode_engine = engines.utf8_engine(options={'convert_unicode':True, 'assert_unicode':True})
try:
unicode_engine.execute(unicode_table.insert(), plain_varchar='im not unicode')
assert False
except exceptions.InvalidRequestError, e:
- assert str(e) == "Received non-unicode bind param value 'im not unicode'"
+ assert str(e) == "Unicode type received non-unicode bind param value 'im not unicode'"
finally:
unicode_engine.dispose()