from mediagoblin.tools.common import simple_printer
from sqlalchemy import Table
+from sqlalchemy.sql import select
class TableAlreadyExists(Exception):
pass
to the latest migrations, etc.
"""
- def __init__(self, name, models, migration_registry, session,
+ def __init__(self, name, models, foundations, migration_registry, session,
printer=simple_printer):
"""
Args:
"""
self.name = unicode(name)
self.models = models
+ self.foundations = foundations
self.session = session
self.migration_registry = migration_registry
self._sorted_migrations = None
self.session.bind,
tables=[model.__table__ for model in self.models])
+ def populate_table_foundations(self):
+ """
+ Create the table foundations (default rows) as layed out in FOUNDATIONS
+ in mediagoblin.db.models
+ """
+ for Model, rows in self.foundations.items():
+ self.printer(u' + Laying foundations for %s table\n' %
+ (Model.__name__))
+ for parameters in rows:
+ new_row = Model(**parameters)
+ self.session.add(new_row)
+
def create_new_migration_record(self):
"""
Create a new migration record for this migration set
if self.name == u'__main__':
return u"main mediagoblin tables"
else:
- # TODO: Use the friendlier media manager "human readable" name
- return u'media type "%s"' % self.name
+ return u'plugin "%s"' % self.name
def init_or_migrate(self):
"""
self.init_tables()
# auto-set at latest migration number
- self.create_new_migration_record()
-
+ self.create_new_migration_record()
self.printer(u"done.\n")
+ self.populate_table_foundations()
self.set_current_migration()
return u'inited'
"""Simple helper to get a ref to an already existing table"""
return Table(table_name, metadata, autoload=True,
autoload_with=metadata.bind)
+
+def replace_table_hack(db, old_table, replacement_table):
+ """
+ A function to fully replace a current table with a new one for migrati-
+ -ons. This is necessary because some changes are made tricky in some situa-
+ -tion, for example, dropping a boolean column in sqlite is impossible w/o
+ this method
+
+ :param old_table A ref to the old table, gotten through
+ inspect_table
+
+ :param replacement_table A ref to the new table, gotten through
+ inspect_table
+
+ Users are encouraged to sqlalchemy-migrate replace table solutions, unless
+ that is not possible... in which case, this solution works,
+ at least for sqlite.
+ """
+ surviving_columns = replacement_table.columns.keys()
+ old_table_name = old_table.name
+ for row in db.execute(select(
+ [column for column in old_table.columns
+ if column.name in surviving_columns])):
+
+ db.execute(replacement_table.insert().values(**row))
+ db.commit()
+
+ old_table.drop()
+ db.commit()
+
+ replacement_table.rename(old_table_name)
+ db.commit()