Skip to content

Commit df52e23

Browse files
authored
Add collation option (#564)
Fixes #563
1 parent aed1dd2 commit df52e23

File tree

3 files changed

+60
-2
lines changed

3 files changed

+60
-2
lines changed

MySQLdb/connections.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ class object, used to create cursors (keyword only)
9797
If supplied, the connection character set will be changed
9898
to this character set.
9999
100+
:param str collation:
101+
If ``charset`` and ``collation`` are both supplied, the
102+
character set and collation for the current connection
103+
will be set.
104+
105+
If omitted, empty string, or None, the default collation
106+
for the ``charset`` is implied.
107+
100108
:param str auth_plugin:
101109
If supplied, the connection default authentication plugin will be
102110
changed to this value. Example values:
@@ -167,6 +175,7 @@ class object, used to create cursors (keyword only)
167175

168176
cursorclass = kwargs2.pop("cursorclass", self.default_cursor)
169177
charset = kwargs2.get("charset", "")
178+
collation = kwargs2.pop("collation", "")
170179
use_unicode = kwargs2.pop("use_unicode", True)
171180
sql_mode = kwargs2.pop("sql_mode", "")
172181
self._binary_prefix = kwargs2.pop("binary_prefix", False)
@@ -193,7 +202,7 @@ class object, used to create cursors (keyword only)
193202

194203
if not charset:
195204
charset = self.character_set_name()
196-
self.set_character_set(charset)
205+
self.set_character_set(charset, collation)
197206

198207
if sql_mode:
199208
self.set_sql_mode(sql_mode)
@@ -285,10 +294,13 @@ def begin(self):
285294
"""
286295
self.query(b"BEGIN")
287296

288-
def set_character_set(self, charset):
297+
def set_character_set(self, charset, collation=None):
289298
"""Set the connection character set to charset."""
290299
super().set_character_set(charset)
291300
self.encoding = _charset_to_encoding.get(charset, charset)
301+
if collation:
302+
self.query("SET NAMES %s COLLATE %s" % (charset, collation))
303+
self.store_result()
292304

293305
def set_sql_mode(self, sql_mode):
294306
"""Set the connection sql_mode. See MySQL documentation for

doc/user_guide.rst

+16
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,22 @@ connect(parameters...)
348348

349349
*This must be a keyword parameter.*
350350

351+
collation
352+
If ``charset`` and ``collation`` are both supplied, the
353+
character set and collation for the current connection
354+
will be set.
355+
356+
If omitted, empty string, or None, the default collation
357+
for the ``charset`` is implied by the database server.
358+
359+
To learn more about the quiddities of character sets and
360+
collations, consult the `MySQL docs
361+
<https://dev.mysql.com/doc/refman/8.0/en/charset.html>`_
362+
and `MariaDB docs
363+
<https://mariadb.com/kb/en/character-sets/>`_
364+
365+
*This must be a keyword parameter.*
366+
351367
sql_mode
352368
If present, the session SQL mode will be set to the given
353369
string. For more information on sql_mode, see the MySQL

tests/test_MySQLdb_nonstandard.py

+30
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,33 @@ def test_context_manager(self):
114114
with connection_factory() as conn:
115115
self.assertFalse(conn.closed)
116116
self.assertTrue(conn.closed)
117+
118+
119+
class TestCollation(unittest.TestCase):
120+
"""Test charset and collation connection options."""
121+
122+
def setUp(self):
123+
# Initialize a connection with a non-default character set and
124+
# collation.
125+
self.conn = connection_factory(
126+
charset="utf8mb4",
127+
collation="utf8mb4_esperanto_ci",
128+
)
129+
130+
def tearDown(self):
131+
self.conn.close()
132+
133+
def test_charset_collation(self):
134+
c = self.conn.cursor()
135+
c.execute(
136+
"""
137+
SHOW VARIABLES WHERE
138+
Variable_Name="character_set_connection" OR
139+
Variable_Name="collation_connection";
140+
"""
141+
)
142+
row = c.fetchall()
143+
charset = row[0][1]
144+
collation = row[1][1]
145+
self.assertEqual(charset, "utf8mb4")
146+
self.assertEqual(collation, "utf8mb4_esperanto_ci")

0 commit comments

Comments
 (0)