- changed status to resolved
pymysql unicode expects unicode or non-unicode for statement/binds at the same time
Issue #3337
resolved
we can set supports_unicode_statements and supports_unicode_binds to True or False and PyMySQL tests pass from 0.4 to 0.6.6. However, if statements is True and binds is False as it is right now, then the "executemany" tests fail, b.c. pymysql is generally using string interpolation to produce the string. Stack is as follows:
#!
$ python -m pytest test/dialect/test_suite.py --dburi "mysql+pymysql://scott:tiger@localhost/test?charset=utf8" -k UnicodeVarcharTest
===================================================================== test session starts ======================================================================
platform darwin -- Python 2.7.5 -- py-1.4.26 -- pytest-2.6.4 -- /Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
plugins: cov, xdist
collected 143 items
test/dialect/test_suite.py <- lib/sqlalchemy/testing/suite/test_types.py::UnicodeVarcharTest_mysql_pymysql::test_empty_strings_varchar PASSED
test/dialect/test_suite.py <- lib/sqlalchemy/testing/suite/test_types.py::UnicodeVarcharTest_mysql_pymysql::test_literal PASSED
test/dialect/test_suite.py <- lib/sqlalchemy/testing/suite/test_types.py::UnicodeVarcharTest_mysql_pymysql::test_round_trip PASSED
test/dialect/test_suite.py <- lib/sqlalchemy/testing/suite/test_types.py::UnicodeVarcharTest_mysql_pymysql::test_round_trip_executemany FAILED
=========================================================================== FAILURES ===========================================================================
_________________________________________________ UnicodeVarcharTest_mysql_pymysql.test_round_trip_executemany _________________________________________________
Traceback (most recent call last):
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/testing/suite/test_types.py", line 89, in test_round_trip_executemany
for i in range(3)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/engine/base.py", line 1978, in execute
return connection.execute(statement, *multiparams, **params)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/engine/base.py", line 914, in execute
return meth(self, multiparams, params)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/sql/elements.py", line 323, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/engine/base.py", line 1010, in _execute_clauseelement
compiled_sql, distilled_params
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/engine/base.py", line 1146, in _execute_context
context)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/engine/base.py", line 1335, in _handle_dbapi_exception
util.reraise(*exc_info)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/engine/base.py", line 1116, in _execute_context
context)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/dialects/mysql/mysqldb.py", line 95, in do_executemany
rowcount = cursor.executemany(statement, parameters)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pymysql/cursors.py", line 148, in executemany
self._get_db().encoding)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pymysql/cursors.py", line 162, in _do_execute_many
v = values % escape(next(args), conn)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 64: ordinal not in range(128)
=================================================================== short test summary info ====================================================================
FAIL test/dialect/test_suite.py::UnicodeVarcharTest_mysql_pymysql::()::test_round_trip_executemany
======================================================== 139 tests deselected by '-kUnicodeVarcharTest' ========================================================
====================================================== 1 failed, 3 passed, 139 deselected in 0.27 seconds ======================================================
classics-MacBook-Pro:sqlalchemy classic$
the fix works all the way back for pymysql 0.4 which was five years ago so this is good for 0.9.
Comments (2)
-
reporter -
reporter - Fixed unicode support for PyMySQL when using an "executemany"
operation with unicode parameters. SQLAlchemy now passes both
the statement as well as the bound parameters as unicode
objects, as PyMySQL generally uses string interpolation
internally to produce the final statement, and in the case of
executemany does the "encode" step only on the final statement.
fixes
#3337
→ <<cset db853306c404>>
- Fixed unicode support for PyMySQL when using an "executemany"
operation with unicode parameters. SQLAlchemy now passes both
the statement as well as the bound parameters as unicode
objects, as PyMySQL generally uses string interpolation
internally to produce the final statement, and in the case of
executemany does the "encode" step only on the final statement.
fixes
- Log in to comment
#3337(cherry picked from commit dcf5408f7d315b4d9ddec5d0d696eb364d763099)
Conflicts: lib/sqlalchemy/dialects/mysql/pymysql.py
→ <<cset 41ca5c8c6769>>