Support %% and precedence spaces in Cursor.executemany()

fixes #449
This commit is contained in:
INADA Naoki
2016-05-10 01:12:36 +09:00
3 changed files with 20 additions and 3 deletions

View File

@@ -12,7 +12,10 @@ from . import err
#: Regular expression for :meth:`Cursor.executemany`.
#: executemany only suports simple bulk insert.
#: You can use it to load large dataset.
RE_INSERT_VALUES = re.compile(r"""(INSERT\s.+\sVALUES\s+)(\(\s*(?:%s|%\(.+\)s)\s*(?:,\s*(?:%s|%\(.+\)s)\s*)*\))(\s*(?:ON DUPLICATE.*)?)\Z""",
RE_INSERT_VALUES = re.compile(
r"\s*(INSERT\s.+\sVALUES\s+)" +
r"(\(\s*(?:%s|%\(.+\)s)\s*(?:,\s*(?:%s|%\(.+\)s)\s*)*\))" +
r"(\s*(?:ON DUPLICATE.*)?)\Z",
re.IGNORECASE | re.DOTALL)
@@ -170,7 +173,7 @@ class Cursor(object):
m = RE_INSERT_VALUES.match(query)
if m:
q_prefix = m.group(1)
q_prefix = m.group(1) % ()
q_values = m.group(2).rstrip()
q_postfix = m.group(3) or ''
assert q_values[0] == '(' and q_values[-1] == ')'

View File

@@ -99,3 +99,16 @@ class CursorTest(base.PyMySQLTestCase):
data_dict = [{'data': i} for i in xrange(10)]
cursor.executemany("insert into test (data) values (%(data)s)", data_dict)
self.assertTrue(cursor._executed.endswith(",(7),(8),(9)"), 'execute many with %(data)s not in one query')
# %% in column set
cursor.execute("""\
CREATE TABLE percent_test (
`A%` INTEGER,
`B%` INTEGER)""")
try:
q = "INSERT INTO percent_test (`A%%`, `B%%`) VALUES (%s, %s)"
self.assertIsNotNone(pymysql.cursors.RE_INSERT_VALUES.match(q)
cursor.executemany(q, [(3, 4), (5, 6)])
self.assertTrue(cursor._executed.endswith("(3, 4),(5, 6)"), "executemany with %% not in one query")
finally:
cursor.execute("DROP TABLE IF EXISTS percent_test")

View File

@@ -10,6 +10,7 @@ if not (PYPY or JYTHON or IRONPYTHON):
@atexit.register
def report_uncollectable():
import gc
if not gc.garbage:
print("No garbages!")
return