[LNT] r309065 - DeSQLify the migrations
Chris Matthews via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 25 17:37:56 PDT 2017
Author: cmatthews
Date: Tue Jul 25 17:37:56 2017
New Revision: 309065
URL: http://llvm.org/viewvc/llvm-project?rev=309065&view=rev
Log:
DeSQLify the migrations
The SQL in the LNT migrations has always been fragile. This removes
the SQL in favor of SQLAlchemy's primatives instead.
In preperation for MySQL support in LNT, I have refactored the
migrations to use more SQLAlchemy features. I have replaced update and
deletes with the corrosponding SQLAlchemy expression langauge calls. I
have also added some common utility functions to modify table structure,
and made those using SQLAlchemy DDL system, so we should be able to
customize them based on the backend.
I updated all 14 current migrations, so they have no raw SQL.
Added:
lnt/trunk/lnt/server/db/migrations/util.py
Modified:
lnt/trunk/lnt/server/db/migrations/upgrade_12_to_13.py
lnt/trunk/lnt/server/db/migrations/upgrade_13_to_14.py
lnt/trunk/lnt/server/db/migrations/upgrade_3_to_4.py
lnt/trunk/lnt/server/db/migrations/upgrade_4_to_5.py
lnt/trunk/lnt/server/db/migrations/upgrade_5_to_6.py
lnt/trunk/lnt/server/db/migrations/upgrade_6_to_7.py
lnt/trunk/lnt/server/db/migrations/upgrade_8_to_9.py
lnt/trunk/lnt/server/db/migrations/upgrade_9_to_10.py
Modified: lnt/trunk/lnt/server/db/migrations/upgrade_12_to_13.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/db/migrations/upgrade_12_to_13.py?rev=309065&r1=309064&r2=309065&view=diff
==============================================================================
--- lnt/trunk/lnt/server/db/migrations/upgrade_12_to_13.py (original)
+++ lnt/trunk/lnt/server/db/migrations/upgrade_12_to_13.py Tue Jul 25 17:37:56 2017
@@ -3,10 +3,13 @@ import sqlalchemy
from sqlalchemy import Column, String, Binary
Base = sqlalchemy.ext.declarative.declarative_base()
+
+
class TestSuiteJSONSchema(Base):
__tablename__ = "TestSuiteJSONSchemas"
testsuite_name = Column("TestSuiteName", String(256), primary_key=True)
jsonschema = Column("JSONSchema", Binary)
+
def upgrade(engine):
Base.metadata.create_all(engine)
Modified: lnt/trunk/lnt/server/db/migrations/upgrade_13_to_14.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/db/migrations/upgrade_13_to_14.py?rev=309065&r1=309064&r2=309065&view=diff
==============================================================================
--- lnt/trunk/lnt/server/db/migrations/upgrade_13_to_14.py (original)
+++ lnt/trunk/lnt/server/db/migrations/upgrade_13_to_14.py Tue Jul 25 17:37:56 2017
@@ -4,71 +4,86 @@
# them if they are not empty, as previously the test-suite name was different
# from the prefix used in the tables. In yaml schemas the name and prefix is
# always the same so we have to rename from `Compile_XXXX` to `compile_XXX`.
-import sqlalchemy
+import collections
+from sqlalchemy import delete, select, update, func
-def _drop_suite(trans, name):
- trans.execute('''
-DELETE FROM "TestSuiteOrderFields"
- WHERE "TestSuiteID" IN
- (SELECT "ID" FROM "TestSuite" WHERE "Name" = \'compile\')
-''')
- trans.execute('''
-DELETE FROM "TestSuiteMachineFields"
- WHERE "TestSuiteID" IN
- (SELECT "ID" FROM "TestSuite" WHERE "Name" = \'compile\')
-''')
- trans.execute('''
-DELETE FROM "TestSuiteRunFields"
- WHERE "TestSuiteID" IN
- (SELECT "ID" FROM "TestSuite" WHERE "Name" = \'compile\')
-''')
- trans.execute('''
-DELETE FROM "TestSuiteSampleFields"
- WHERE "TestSuiteID" IN
- (SELECT "ID" FROM "TestSuite" WHERE "Name" = \'compile\')
-''')
- trans.execute('DELETE FROM "TestSuite" WHERE "Name" = \'compile\'')
+from lnt.server.db.migrations.util import introspect_table, rename_table
+
+
+def _drop_suite(trans, name, engine):
+ """Drop the suite name.
+
+ This patches up the suite description tables for Order Fields,
+ Machine Fields, Run Fields and Sample Fields.
+
+ After than remove the suite directly from the TestSuite table.
+ """
+
+ test_suite = introspect_table(engine, 'TestSuite')
+
+ test_suite_id = trans.execute(
+ select([test_suite.c.ID]).where(test_suite.c.Name == name)) \
+ .scalar()
+
+ drop_fields(engine, test_suite_id, 'TestSuiteOrderFields', trans)
+ drop_fields(engine, test_suite_id, 'TestSuiteMachineFields', trans)
+ drop_fields(engine, test_suite_id, 'TestSuiteRunFields', trans)
+ drop_fields(engine, test_suite_id, 'TestSuiteSampleFields', trans)
+
+ trans.execute(delete(test_suite).where(test_suite.c.Name == name))
+
+
+def drop_fields(engine, test_suite_id, name, trans):
+ """In the *Fields Tables, drop entries related to the test_suite_id.
+ """
+ fields_table = introspect_table(engine, name)
+ order_files = delete(fields_table,
+ fields_table.c.TestSuiteID == test_suite_id)
+ trans.execute(order_files)
+ return fields_table
+
+
+TableRename = collections.namedtuple('TableRename', 'old_name new_name')
def upgrade(engine):
- tablenames = [
- ('Compile_Baseline', 'compile_Baseline'),
- ('Compile_ChangeIgnore', 'compile_ChangeIgnore'),
- ('Compile_RegressionIndicator', 'compile_RegressionIndicator'),
- ('Compile_FieldChange', 'compile_FieldChange'),
- ('Compile_FieldChangeV2', 'compile_FieldChangeV2'),
- ('Compile_Profile', 'compile_Profile'),
- ('Compile_Regression', 'compile_Regression'),
- ('Compile_Sample', 'compile_Sample'),
- ('Compile_Run', 'compile_Run'),
- ('Compile_Order', 'compile_Order'),
- ('Compile_Test', 'compile_Test'),
- ('Compile_Machine', 'compile_Machine'),
+ table_renames = [
+ TableRename('Compile_Baseline', 'compile_Baseline'),
+ TableRename('Compile_ChangeIgnore', 'compile_ChangeIgnore'),
+ TableRename('Compile_RegressionIndicator', 'compile_RegressionIndicator'),
+ TableRename('Compile_FieldChange', 'compile_FieldChange'),
+ TableRename('Compile_FieldChangeV2', 'compile_FieldChangeV2'),
+ TableRename('Compile_Profile', 'compile_Profile'),
+ TableRename('Compile_Regression', 'compile_Regression'),
+ TableRename('Compile_Sample', 'compile_Sample'),
+ TableRename('Compile_Run', 'compile_Run'),
+ TableRename('Compile_Order', 'compile_Order'),
+ TableRename('Compile_Test', 'compile_Test'),
+ TableRename('Compile_Machine', 'compile_Machine'),
]
all_empty = True
- for name, _ in tablenames:
- num = engine.execute('SELECT COUNT(*) FROM "%s"' % name).first()
- if num[0] > 0:
+ for rename in table_renames:
+ tab = introspect_table(engine, rename.old_name)
+ size = select([func.count(tab.c.ID)])
+ num = engine.execute(size).scalar()
+
+ if num > 0:
all_empty = False
break
-
+ test_suite = introspect_table(engine, 'TestSuite')
with engine.begin() as trans:
- # If nobody ever put data into the compile suite drop it
+ # If nobody ever put data into the compile suite drop it.
if all_empty:
- for name, _ in tablenames:
- trans.execute('DROP TABLE "%s"' % name)
- _drop_suite(trans, 'compile')
+ for name, _ in table_renames:
+ tab = introspect_table(engine, name)
+ tab.drop()
+ _drop_suite(trans, 'compile', engine)
else:
- for old_name, new_name in tablenames:
- env = {'old_name': old_name, 'new_name': new_name}
- trans.execute('''
-ALTER TABLE "%(old_name)s" RENAME TO "%(new_name)s_x"
-''' % env)
- trans.execute('''
-ALTER TABLE "%(new_name)s_x" RENAME TO \"%(new_name)s\"
-''' % env)
+ for rename in table_renames:
+ tab = introspect_table(engine, rename.old_name)
+ rename_table(engine, tab, rename.new_name)
# Just change the DB_Key to match the name
- trans.execute('''
-UPDATE "TestSuite" SET "DBKeyName" = \'compile\' WHERE "Name" = \'compile\'
-''')
+ trans.execute(update(test_suite)
+ .where(test_suite.c.Name == 'compile')
+ .values(DBKeyName='compile'))
Modified: lnt/trunk/lnt/server/db/migrations/upgrade_3_to_4.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/db/migrations/upgrade_3_to_4.py?rev=309065&r1=309064&r2=309065&view=diff
==============================================================================
--- lnt/trunk/lnt/server/db/migrations/upgrade_3_to_4.py (original)
+++ lnt/trunk/lnt/server/db/migrations/upgrade_3_to_4.py Tue Jul 25 17:37:56 2017
@@ -1,18 +1,12 @@
# Version 4 of the database adds the bigger_is_better column to StatusField.
-import os
-import sys
+from sqlalchemy import Column, Integer
-import sqlalchemy
+from lnt.server.db.migrations.util import introspect_table, add_column
-###
-# Upgrade TestSuite
def upgrade(engine):
- # Add our new column. SQLAlchemy doesn't really support adding a new column to an
- # existing table, so instead of requiring SQLAlchemy-Migrate, just execute the raw SQL.
- with engine.begin() as trans:
- trans.execute("""
-ALTER TABLE "TestSuiteSampleFields"
-ADD COLUMN "bigger_is_better" INTEGER DEFAULT 0
-""")
+ test_suite_sample_fields = introspect_table(engine,
+ 'TestSuiteSampleFields')
+ bigger_is_better = Column('bigger_is_better', Integer, default=0)
+ add_column(engine, test_suite_sample_fields, bigger_is_better)
Modified: lnt/trunk/lnt/server/db/migrations/upgrade_4_to_5.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/db/migrations/upgrade_4_to_5.py?rev=309065&r1=309064&r2=309065&view=diff
==============================================================================
--- lnt/trunk/lnt/server/db/migrations/upgrade_4_to_5.py (original)
+++ lnt/trunk/lnt/server/db/migrations/upgrade_4_to_5.py Tue Jul 25 17:37:56 2017
@@ -1,45 +1,41 @@
# Version 5 adds a "score" Sample type.
-import os
-import sys
-
-import sqlalchemy
-from sqlalchemy import *
-
-###
-# Upgrade TestSuite
-
# Import the original schema from upgrade_0_to_1 since upgrade_4_to_5 does not
# change the actual schema.
+from sqlalchemy import update, Column, Float
+from sqlalchemy.orm import sessionmaker
+
import lnt.server.db.migrations.upgrade_0_to_1 as upgrade_0_to_1
+from lnt.server.db.migrations.util import add_column, introspect_table
+
def upgrade(engine):
# Create a session.
- session = sqlalchemy.orm.sessionmaker(engine)()
+ session = sessionmaker(engine)()
- real_sample_type = session.query(upgrade_0_to_1.SampleType).\
- filter_by(name = "Real").first()
+ real_sample_type = session.query(upgrade_0_to_1.SampleType). \
+ filter_by(name="Real").first()
ts = session.query(upgrade_0_to_1.TestSuite).filter_by(name='nts').first()
score = upgrade_0_to_1.SampleField(name="score", type=real_sample_type,
- info_key=".score",)
+ info_key=".score")
ts.sample_fields.append(score)
session.add(ts)
session.commit()
session.close()
- # upgrade_3_to_4.py added this column, so it is not in the ORM.
+ test_suite_sample_fields = introspect_table(engine, 'TestSuiteSampleFields')
+
+ set_scores = update(test_suite_sample_fields) \
+ .where(test_suite_sample_fields.c.Name == "score") \
+ .values(bigger_is_better=1)
+
with engine.begin() as trans:
- trans.execute("""
-UPDATE "TestSuiteSampleFields"
-SET bigger_is_better=1
-WHERE "Name"='score'
-""")
- # FIXME: This is obviously not the right way to do this, but I gave up
- # trying to find out how to do it properly in SQLAlchemy without
- # SQLAlchemy-migrate installed.
- trans.execute("""
-ALTER TABLE "NT_Sample"
-ADD COLUMN "score" FLOAT
-""")
+ trans.execute(set_scores)
+
+ # Give the NT table a score column.
+
+ nt_sample = introspect_table(engine, 'NT_Sample')
+ score = Column('score', Float)
+ add_column(engine, nt_sample, score)
Modified: lnt/trunk/lnt/server/db/migrations/upgrade_5_to_6.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/db/migrations/upgrade_5_to_6.py?rev=309065&r1=309064&r2=309065&view=diff
==============================================================================
--- lnt/trunk/lnt/server/db/migrations/upgrade_5_to_6.py (original)
+++ lnt/trunk/lnt/server/db/migrations/upgrade_5_to_6.py Tue Jul 25 17:37:56 2017
@@ -1,10 +1,8 @@
# Version 6 adds a "mem_bytes"" Sample type to "nts".
-import os
-import sys
-
import sqlalchemy
from sqlalchemy import *
+from lnt.server.db.migrations.util import add_column, introspect_table
###
# Upgrade TestSuite
@@ -13,12 +11,13 @@ from sqlalchemy import *
# change the actual schema.
import lnt.server.db.migrations.upgrade_0_to_1 as upgrade_0_to_1
+
def upgrade(engine):
# Create a session.
session = sqlalchemy.orm.sessionmaker(engine)()
real_sample_type = session.query(upgrade_0_to_1.SampleType).\
- filter_by(name = "Real").first()
+ filter_by(name="Real").first()
ts = session.query(upgrade_0_to_1.TestSuite).filter_by(name='nts').first()
mem_bytes = upgrade_0_to_1.SampleField(name="mem_bytes",
@@ -29,18 +28,16 @@ def upgrade(engine):
session.commit()
session.close()
+ test_suite_sample_fields = introspect_table(engine, 'TestSuiteSampleFields')
+
+ set_mem = update(test_suite_sample_fields) \
+ .where(test_suite_sample_fields.c.Name == "mem_bytes") \
+ .values(bigger_is_better=0)
+
# upgrade_3_to_4.py added this column, so it is not in the ORM.
with engine.begin() as trans:
- trans.execute("""
-UPDATE "TestSuiteSampleFields"
-SET bigger_is_better=0
-WHERE "Name"='mem_bytes'
-""")
-
- # FIXME: This is obviously not the right way to do this, but I gave up
- # trying to find out how to do it properly in SQLAlchemy without
- # SQLAlchemy-migrate installed.
- trans.execute("""
-ALTER TABLE "NT_Sample"
-ADD COLUMN "mem_bytes" FLOAT
-""")
+ trans.execute(set_mem)
+
+ nt_sample = introspect_table(engine, 'NT_Sample')
+ mem_bytes = Column('mem_bytes', Float)
+ add_column(engine, nt_sample, mem_bytes)
Modified: lnt/trunk/lnt/server/db/migrations/upgrade_6_to_7.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/db/migrations/upgrade_6_to_7.py?rev=309065&r1=309064&r2=309065&view=diff
==============================================================================
--- lnt/trunk/lnt/server/db/migrations/upgrade_6_to_7.py (original)
+++ lnt/trunk/lnt/server/db/migrations/upgrade_6_to_7.py Tue Jul 25 17:37:56 2017
@@ -1,9 +1,6 @@
# Version 7 adds a "hash" Sample type & adds a sample field of
# this type for the NTS test suite.
-import os
-import sys
-
import sqlalchemy
###
@@ -14,6 +11,8 @@ import sqlalchemy
from lnt.server.db.migrations.upgrade_0_to_1 \
import SampleType, TestSuite, SampleField
+from lnt.server.db.migrations.util import add_column, introspect_table
+
def upgrade(engine):
# Create a session.
@@ -41,15 +40,8 @@ def upgrade(engine):
session.commit()
session.close()
- with engine.begin() as trans:
- trans.execute("""
-ALTER TABLE "NT_Sample"
-ADD COLUMN "hash_status" INTEGER
-""")
- # For MD5 hashes, 32 characters is enough to store the full has.
- # Assume that for hashing schemes producing longer hashes, storing
- # just the first 32 characters is good enough for our use case.
- trans.execute("""
- ALTER TABLE "NT_Sample"
- ADD COLUMN "hash" VARCHAR(32)
- """)
+ nt_sample = introspect_table(engine, 'NT_Sample')
+ hash_status = sqlalchemy.Column('hash_status', sqlalchemy.Integer)
+ hash_string = sqlalchemy.Column('hash', sqlalchemy.String(32))
+ add_column(engine, nt_sample, hash_status)
+ add_column(engine, nt_sample, hash_string)
Modified: lnt/trunk/lnt/server/db/migrations/upgrade_8_to_9.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/db/migrations/upgrade_8_to_9.py?rev=309065&r1=309064&r2=309065&view=diff
==============================================================================
--- lnt/trunk/lnt/server/db/migrations/upgrade_8_to_9.py (original)
+++ lnt/trunk/lnt/server/db/migrations/upgrade_8_to_9.py Tue Jul 25 17:37:56 2017
@@ -1,22 +1,17 @@
# Version 9 of the database updates Sample to add the profile field, and
# adds Profiles.
-import os
-import sys
-
import sqlalchemy
from sqlalchemy import *
-from sqlalchemy.schema import Index
from sqlalchemy.orm import relation
# Import the original schema from upgrade_0_to_1 since upgrade_1_to_2 does not
# change the actual schema, but rather adds functionality vis-a-vis orders.
import lnt.server.db.migrations.upgrade_0_to_1 as upgrade_0_to_1
import lnt.server.db.migrations.upgrade_2_to_3 as upgrade_2_to_3
+from lnt.server.db.migrations.util import add_column, introspect_table
-###
-# Upgrade TestSuite
def add_profiles(test_suite):
"""Given a test suite with a database connection and a test-suite
name, make the profile sqlalchemy database objects for that test-suite.
@@ -30,23 +25,24 @@ def add_profiles(test_suite):
class Profile(Base):
__tablename__ = db_key_name + '_Profile'
-
+
id = Column("ID", Integer, primary_key=True)
created_time = Column("CreatedTime", DateTime)
accessed_time = Column("AccessedTime", DateTime)
filename = Column("Filename", String(256))
counters = Column("Counters", String(512))
-
+
return Base
+
def upgrade_testsuite(engine, name):
# Grab Test Suite.
session = sqlalchemy.orm.sessionmaker(engine)()
- test_suite = session.query(upgrade_0_to_1.TestSuite).\
- filter_by(name=name).first()
- assert(test_suite is not None)
+ test_suite = session.query(upgrade_0_to_1.TestSuite). \
+ filter_by(name=name).first()
+ assert (test_suite is not None)
db_key_name = test_suite.db_key_name
-
+
# Add FieldChange to the test suite.
Base = add_profiles(test_suite)
Base.metadata.create_all(engine)
@@ -55,11 +51,10 @@ def upgrade_testsuite(engine, name):
session.commit()
session.close()
- with engine.begin() as trans:
- trans.execute("""
-ALTER TABLE "%s_Sample"
-ADD COLUMN "ProfileID" INTEGER
-""" % (db_key_name,))
+ ts_sample_table = introspect_table(engine, "{}_Sample".format(db_key_name))
+ profile_id = Column('ProfileID', Integer)
+ add_column(engine, ts_sample_table, profile_id)
+
def upgrade(engine):
# Create our FieldChangeField table and commit.
Modified: lnt/trunk/lnt/server/db/migrations/upgrade_9_to_10.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/db/migrations/upgrade_9_to_10.py?rev=309065&r1=309064&r2=309065&view=diff
==============================================================================
--- lnt/trunk/lnt/server/db/migrations/upgrade_9_to_10.py (original)
+++ lnt/trunk/lnt/server/db/migrations/upgrade_9_to_10.py Tue Jul 25 17:37:56 2017
@@ -6,8 +6,12 @@ import sqlalchemy
###
# Import the original schema from upgrade_0_to_1 since upgrade_5_to_6 does not
# change the actual schema.
+from sqlalchemy import update, Column, Float
+
import lnt.server.db.migrations.upgrade_0_to_1 as upgrade_0_to_1
+from lnt.server.db.migrations.util import add_column, introspect_table
+
def upgrade(engine):
# Create a session.
@@ -25,14 +29,15 @@ def upgrade(engine):
session.commit()
session.close()
+ test_suite_sample_fields = introspect_table(engine, 'TestSuiteSampleFields')
+ update_code_size = update(test_suite_sample_fields) \
+ .where(test_suite_sample_fields.c.Name == "code_size") \
+ .values(bigger_is_better=0)
# upgrade_3_to_4.py added this column, so it is not in the ORM.
+
with engine.begin() as trans:
- trans.execute("""
-UPDATE "TestSuiteSampleFields"
-SET bigger_is_better=0
-WHERE "Name"='code_size'
-""")
- trans.execute("""
-ALTER TABLE "NT_Sample"
-ADD COLUMN "code_size" FLOAT
-""")
+ trans.execute(update_code_size)
+
+ nt_sample = introspect_table(engine, 'NT_Sample')
+ code_size = Column('code_size', Float)
+ add_column(engine, nt_sample, code_size)
Added: lnt/trunk/lnt/server/db/migrations/util.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/db/migrations/util.py?rev=309065&view=auto
==============================================================================
--- lnt/trunk/lnt/server/db/migrations/util.py (added)
+++ lnt/trunk/lnt/server/db/migrations/util.py Tue Jul 25 17:37:56 2017
@@ -0,0 +1,61 @@
+import sqlalchemy
+from sqlalchemy import DDL
+
+
+def add_column(engine, table_to_alter, column_to_add):
+ # type: (sqlalchemy.engine.Engine, sqlalchemy.Table, sqlalchemy.Column) -> None
+ """Add this column to the table.
+
+ This is a stopgap to a real migration system. Inspect the Column pass
+ and try to issue an ALTER command to make the column. Detect Column
+ default, and add that.
+
+ Be careful, this does not support corner cases like most Column keywords
+ or any fancy Column settings.
+
+ :param engine: to execute on.
+ :param table_to_alter: the Table to add the column to.
+ :param column_to_add: Column that does not have anything fancy like
+ autoincrement.
+
+ """
+ column_name = column_to_add.name
+ col_type = column_to_add.type
+ if not column_to_add.default:
+ default = ""
+ else:
+ default = "DEFAULT {}".format(column_to_add.default.arg)
+ add_score = DDL("ALTER TABLE %(table)s ADD COLUMN %(column_name)s %(col_type)s %(default)s",
+ context=dict(column_name=column_name,
+ col_type=col_type,
+ default=default))
+ add_score.execute(bind=engine, target=table_to_alter)
+
+
+def introspect_table(engine, name):
+ # type: (sqlalchemy.engine.Engine, str) -> sqlalchemy.Table
+ """Create a SQLAlchemy Table from the table name in the current DB.
+
+ Used to make a Table object from something already in the DB."""
+ md = sqlalchemy.MetaData(engine)
+ target_table = sqlalchemy.Table(name, md, autoload=True)
+ return target_table
+
+
+def rename_table(engine, old_table, new_name):
+ # type: (sqlalchemy.engine.Engine, sqlalchemy.Table, str) -> None
+ """Rename the old_table to new_table.
+
+ Renames the table by Old_Table -> New_Table_x -> New_Table.
+
+ :param engine: to execute on.
+ :param old_table: the Table to rename.
+ :param new_name: the string name to change the table to.
+
+ """
+ rename = DDL("ALTER TABLE %(table)s RENAME TO %(new_name)s_x",
+ context=dict(new_name=new_name))
+ rename.execute(bind=engine, target=old_table)
+ rename = DDL("ALTER TABLE %(new_name)s_x RENAME TO %(new_name)s",
+ context=dict(new_name=new_name))
+ rename.execute(bind=engine)
More information about the llvm-commits
mailing list