From f3f06820d7a05216cdd360203ce964f0c8d34ec4 Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Wed, 4 Feb 2015 17:21:29 +0900 Subject: [PATCH 1/3] Improve datetime, date, time and timedelta format. --- pymysql/converters.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/pymysql/converters.py b/pymysql/converters.py index 70867f7e..be6bd0d7 100644 --- a/pymysql/converters.py +++ b/pymysql/converters.py @@ -76,21 +76,29 @@ def escape_timedelta(obj): seconds = int(obj.seconds) % 60 minutes = int(obj.seconds // 60) % 60 hours = int(obj.seconds // 3600) % 24 + int(obj.days) * 24 - return escape_str('%02d:%02d:%02d' % (hours, minutes, seconds)) + if obj.microseconds: + fmt = "'{0:02d}:{1:02d}:{2:02d}.{3:06d}'" + else: + fmt = "'{0:02d}:{1:02d}:{2:02d}'" + return fmt.format(hours, minutes, seconds, obj.microseconds) def escape_time(obj): - s = "%02d:%02d:%02d" % (int(obj.hour), int(obj.minute), - int(obj.second)) if obj.microsecond: - s += ".{0:06}".format(obj.microsecond) - - return escape_str(s) + fmt = "'{0.hour:02}:{0.minute:02}:{0.second:02}.{0.microsecond:06}'" + else: + fmt = "'{0.hour:02}:{0.minute:02}:{0.second:02}'" + return fmt.format(obj) def escape_datetime(obj): - return escape_str(obj.isoformat(' ')) + if obj.microsecond: + fmt = "'{0.year:04}-{0.month:02}-{0.day:02} {0.hour:02}:{0.minute:02}:{0.second:02}.{0.microsecond:06}'" + else: + fmt = "'{0.year:04}-{0.month:02}-{0.day:02} {0.hour:02}:{0.minute:02}:{0.second:02}'" + return fmt.format(obj) def escape_date(obj): - return escape_str(obj.isoformat()) + fmt = "'{0.year:04}-{0.month:02}-{0.day:02}'" + return fmt.format(obj) def escape_struct_time(obj): return escape_datetime(datetime.datetime(*obj[:6])) From 5157c9b7d058f764695a35684b599e0cbac22d9c Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Wed, 4 Feb 2015 17:26:29 +0900 Subject: [PATCH 2/3] Use surrogateescape for escaping bytes on PY3 Fixes #295 --- pymysql/converters.py | 3 ++- pymysql/cursors.py | 10 ++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/pymysql/converters.py b/pymysql/converters.py index be6bd0d7..893c7c66 100644 --- a/pymysql/converters.py +++ b/pymysql/converters.py @@ -67,7 +67,8 @@ def escape_unicode(value): return escape_str(value) def escape_bytes(value): - return "x'%s'" % binascii.hexlify(value).decode(sys.getdefaultencoding()) + # escape_bytes is calld only on Python 3. + return escape_str(value.decode('ascii', 'surrogateescape')) def escape_None(value): return 'NULL' diff --git a/pymysql/cursors.py b/pymysql/cursors.py index b8d9ea48..d22af593 100644 --- a/pymysql/cursors.py +++ b/pymysql/cursors.py @@ -161,13 +161,19 @@ def _do_execute_many(self, prefix, values, postfix, args, max_stmt_length, encod args = iter(args) v = values % escape(next(args), conn) if isinstance(v, text_type): - v = v.encode(encoding) + if PY2: + v = v.encode(encoding) + else: + v = v.encode(encoding, 'surrogateescape') sql += v rows = 0 for arg in args: v = values % escape(arg, conn) if isinstance(v, text_type): - v = v.encode(encoding) + if PY2: + v = v.encode(encoding) + else: + v = v.encode(encoding, 'surrogateescape') if len(sql) + len(v) + len(postfix) + 1 > max_stmt_length: rows += self.execute(sql + postfix) sql = bytearray(prefix) From 6f4b452a24355dfbc1b423197b1b604b927d8f1c Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Wed, 4 Feb 2015 17:32:33 +0900 Subject: [PATCH 3/3] Add more check to investigate Travis fails test_issue_36 --- pymysql/tests/test_issues.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pymysql/tests/test_issues.py b/pymysql/tests/test_issues.py index a64b15c2..a3cac4ae 100644 --- a/pymysql/tests/test_issues.py +++ b/pymysql/tests/test_issues.py @@ -1,4 +1,5 @@ import datetime +import time import warnings import pymysql @@ -226,6 +227,9 @@ def test_issue_36(self): # check the process list from the other connection try: + # Wait since Travis-CI sometimes fail this test. + time.sleep(0.1) + c = self.connections[1].cursor() c.execute("show processlist") ids = [row[0] for row in c.fetchall()]