SqlScript: execute multiple statements one by one

Some drivers [f.e. MySQL Connector] do not like multiple statements
being passed to .execute(). They require either passing multi=True
parameter to .execute() that is not DB-API 2.0 defined, or executing
those statements one by one.

For that patch, I've chosen the second option to stay away from driver
specific hacks.

Also removed SQLite hack that seems to be related to the same multiple
statements issue.

blueprint enable-mysql-connector

Change-Id: Ic6d53ed1fef8aee9471f3540f06b39cd5ee4ef82
This commit is contained in:
Ihar Hrachyshka 2014-08-02 23:49:46 +02:00
parent be1dd6730a
commit 93ae21007d
3 changed files with 12 additions and 9 deletions

View File

@ -269,5 +269,5 @@ class TestSqlScript(fixture.Pathed, fixture.DB):
# run the change
sqls = SqlScript(src)
sqls.run(self.engine, executemany=False)
sqls.run(self.engine)
tmp_sql_table.metadata.drop_all(self.engine, checkfirst=True)

View File

@ -3,6 +3,8 @@
import logging
import shutil
import sqlparse
from migrate.versioning.script import base
from migrate.versioning.template import Template
@ -24,7 +26,7 @@ class SqlScript(base.BaseScript):
return cls(path)
# TODO: why is step parameter even here?
def run(self, engine, step=None, executemany=True):
def run(self, engine, step=None):
"""Runs SQL script through raw dbapi execute call"""
text = self.source()
# Don't rely on SA's autocommit here
@ -34,13 +36,13 @@ class SqlScript(base.BaseScript):
try:
trans = conn.begin()
try:
# HACK: SQLite doesn't allow multiple statements through
# its execute() method, but it provides executescript() instead
dbapi = conn.engine.raw_connection()
if executemany and getattr(dbapi, 'executescript', None):
dbapi.executescript(text)
else:
conn.execute(text)
# NOTE(ihrachys): script may contain multiple statements, and
# not all drivers reliably handle multistatement queries or
# commands passed to .execute(), so split them and execute one
# by one
for statement in sqlparse.split(text):
if statement:
conn.execute(statement)
trans.commit()
except Exception as e:
log.error("SQL script %s failed: %s", self.path, e)

View File

@ -6,4 +6,5 @@ pbr>=0.5.21,<1.0
SQLAlchemy>=0.7.8
decorator
six>=1.4.1
sqlparse
Tempita >= 0.4