Skip to content

Commit

Permalink
MySqlConne8ctorPython >= 8.0.32 breaks sending binary strings.
Browse files Browse the repository at this point in the history
Do not test with it.
  • Loading branch information
jamadden committed Jun 27, 2023
1 parent 934974f commit d4dd433
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 36 deletions.
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
everything less than 3.7.
- Add the "Requires Python" metadata to prevent installation on Python
< 3.7.
- The minimum supported version of MySQL is 5.3.3.


3.5.0 (2022-09-16)
Expand Down
11 changes: 5 additions & 6 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,11 @@ environment:

# Fully supported 64-bit versions, with testing. This should be
# all the current (non EOL) versions.
# Need gevent for testing.
# - PYTHON: "C:\\Python312-x64"
# PYTHON_VERSION: "3.12.0b3"
# PYTHON_ARCH: "64"
# PYTHON_EXE: python
# APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
- PYTHON: "C:\\Python312-x64"
PYTHON_VERSION: "3.12.0b3"
PYTHON_ARCH: "64"
PYTHON_EXE: python
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022

- PYTHON: "C:\\Python311-x64"
PYTHON_VERSION: "3.11.0"
Expand Down
2 changes: 1 addition & 1 deletion scripts/releases/make-manylinux
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ if [ -d /RelStorage -a -d /opt/python ]; then
rm -rf wheelhouse
mkdir wheelhouse

for variant in `ls -d /opt/python/cp{37,38,39,310,311}*`; do
for variant in `ls -d /opt/python/cp{37,38,39,310,311,312}*`; do
echo "Building $variant"
mkdir /tmp/build
cd /tmp/build
Expand Down
33 changes: 14 additions & 19 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ def read_file(*path):
'zc.zlibstorage',
'zope.testrunner',
'nti.testing',
'gevent >= 1.5a1',
# At this writing, gevent isn't supported on 3.12 yet.
'gevent >= 1.5a1; python_version < "3.12"',
'pyperf',
# Versions of PyPy2 prior to 7.4 (maybe?) are incompatible with
# psutil >= 5.6.4.
Expand Down Expand Up @@ -210,7 +211,7 @@ def read_file(*path):

# pylint:disable=line-too-long
'mysql:platform_python_implementation=="CPython" and (sys_platform != "win32")': [
'mysqlclient >= 1.4, != 2.0.0',
'mysqlclient >= 2.0.0',
],
'mysql:platform_python_implementation=="PyPy" or (sys_platform == "win32")': [
'PyMySQL>=0.6.6',
Expand Down Expand Up @@ -261,28 +262,22 @@ def read_file(*path):
# up too heavy for better parallelism.

# First, mysql
# pymysql on 3.6 on all platforms. We get coverage data from Travis,
# and we get 2.7 from PyPy and Windows.
'PyMySQL >= 0.6.6; python_version == "3.7" or platform_python_implementation == "PyPy" or sys_platform == "win32"',
# mysqlclient (binary) on all CPythons. It's the default,
# except on old Windows. We get coverage from Travis.
'mysqlclient >= 1.4,!=2.0.0;platform_python_implementation=="CPython" and (sys_platform != "win32")',
# mysql-connector-python on Python 3.7 for coverage on Travis and ensuring it works
# on Windows, and PyPy for testing there, since it's one of two pure-python versions.
#'mysql-connector-python >= 8.0.16; python_version == "3.7"',
# 8.0.24 (!) quietly dropped support for Python 2, but they didn't set the
# PyPI metadata right at least up through 8.0.26, so we get an incompatible version
# without this pin.
#'mysql-connector-python >= 8.0.16, < 8.0.24; platform_python_implementation == "PyPy"',
# pymysql on 3.6 on all platforms.
'PyMySQL >= 0.6.6',
# mysqlclient (binary) on all CPythons. It's the default.
'mysqlclient >= 2.0.0',
# mysql-connector-python; one of two pure-python versions
# XXX: >= 8.0.32 has issues with binary values!
'mysql-connector-python == 8.0.31; python_version == "3.11"',

# postgresql
# pure-python
# pg8000 on Python 2.7 or PyPy. We get coverage from Travis, and we also
# get Windows.
'pg8000 >= 1.11.0 ; python_version == "2.7" or platform_python_implementation == "PyPy"',
# pg8000
'pg8000 >= 1.11.0',
# CFFI, runs on all implementations.
# We get coverage from 3.x on Travis and verification it works on Windows from Travis.
# We get 2.7 testing from PyPy on Travis.
'psycopg2cffi >= 2.7.4; python_version == "3.6" or platform_python_implementation == "PyPy"',
'psycopg2cffi >= 2.7.4; python_version == "3.11" or platform_python_implementation == "PyPy"',
# Psycopg2 on all CPython, it's the default
'psycopg2 >= 2.8.3; platform_python_implementation == "CPython"',
],
Expand Down
2 changes: 1 addition & 1 deletion src/relstorage/adapters/batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,6 @@ def _do_inserts(self):
# INSERT INTO table(c1, c2)
# VALUES (%s, %s), (%s, %s), (%s, %s)
# <suffix>
__traceback_info__ = stmt
__traceback_info__ = stmt, params
self.cursor.execute(stmt, params)
return count
30 changes: 22 additions & 8 deletions src/relstorage/adapters/mysql/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class MySQLSchemaInstaller(AbstractSchemaInstaller):
def __init__(self, driver=None, version_detector=None, **kwargs):
self.driver = driver
self.version_detector = version_detector or MySQLVersionDetector()
super(MySQLSchemaInstaller, self).__init__(**kwargs)
super().__init__(**kwargs)

def get_database_name(self, cursor):
cursor.execute("SELECT DATABASE()")
Expand Down Expand Up @@ -141,7 +141,7 @@ def list_views(self, cursor):
return [self._metadata_to_native_str(r[0]) for r in cursor]

def check_compatibility(self, cursor, tables):
super(MySQLSchemaInstaller, self).check_compatibility(cursor, tables)
super().check_compatibility(cursor, tables)
tables_that_are_not_innodb = self.__list_tables_not_innodb(cursor)
if tables_that_are_not_innodb:
raise StorageError(
Expand Down Expand Up @@ -198,11 +198,11 @@ def __convert_all_tables_to_innodb(self, cursor):
def _prepare_with_connection(self, conn, cursor):
from .oidallocator import MySQLOIDAllocator
self.__convert_all_tables_to_innodb(cursor)
super(MySQLSchemaInstaller, self)._prepare_with_connection(conn, cursor)
super()._prepare_with_connection(conn, cursor)
MySQLOIDAllocator(self.driver).garbage_collect_oids(cursor)

def _read_proc_files(self):
name_to_source = super(MySQLSchemaInstaller, self)._read_proc_files()
name_to_source = super()._read_proc_files()

for proc_name, source in name_to_source.items():
# No leading or trailing lines allowed, only the procedure
Expand All @@ -212,7 +212,7 @@ def _read_proc_files(self):
assert proc_name in source
return name_to_source

def create_procedures(self, cursor):
def create_procedures(self, cursor): # pylint:disable=too-many-locals
# Apparently procedures remember the ``character_set_client`` and ``collation_connection``
# that was in use at the time they were defined, and use that
# to perform implicit conversions on arguments and even internally. If we have
Expand Down Expand Up @@ -240,8 +240,22 @@ def create_procedures(self, cursor):
set_lock_timeout = 'SET innodb_lock_wait_timeout = 1;'
for_share = 'LOCK IN SHARE MODE'

cursor.execute('SET SESSION character_set_client = utf8, '
'collation_connection = utf8_general_ci')
# MySQL added the utf8mb4 charset in version 5.5.3. utf8mb4
# fully implements the current standard. Now utf8 is an alias
# for utf8mb3 and will be switched to utf8mb4.
# collation names: charset-algo-case
# algo: bin (binary); general (simplified, speedy); unicode (full)
# case: ci (insensitive); cs (sensitive)
#
# XXX: MySqlConnectorPython is complaining about encoding in >= 8.0.32:
# mysql.connector.errors.Warning: (
# 1300,
# bytearray(b"Invalid utf8mb4 character string: \'800363\'"))
#
# On ``INSERT INTO object_state...`` where the values are all parameterized
# and are all bytstrings
cursor.execute('SET SESSION character_set_client = utf8mb4, '
'collation_connection = utf8mb4_general_ci')

for name, create_stmt in self.procedures.items():
__traceback_info__ = name
Expand Down Expand Up @@ -289,7 +303,7 @@ def _after_zap_all_tables(self, cursor, slow=False):
self.create_tables(cursor)
logger.debug("Done creating tables after drop")
else:
super(MySQLSchemaInstaller, self)._after_zap_all_tables(cursor, slow)
super()._after_zap_all_tables(cursor, slow)


class MySQLVersionDetector(DatabaseHelpersMixin):
Expand Down
2 changes: 1 addition & 1 deletion version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.5.1.dev0
4.0.0.dev0

0 comments on commit d4dd433

Please sign in to comment.