I made some changes in this commit to help out with other people trying to work

around the SQLite problems with Alter table. I added a new function to
migration_tools (replace_table) which does all the work I did in my migration of
core__users, but is now usable for other migrations.
This commit is contained in:
tilly-Q 2013-10-09 17:11:41 -04:00
parent a4609dd32b
commit e5196ff000
2 changed files with 31 additions and 21 deletions

View File

@ -16,6 +16,7 @@
from mediagoblin.tools.common import simple_printer
from sqlalchemy import Table
from sqlalchemy.sql import select
class TableAlreadyExists(Exception):
pass
@ -286,3 +287,29 @@ def inspect_table(metadata, table_name):
"""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(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"""
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.name=old_table_name
db.commit()

View File

@ -27,7 +27,8 @@ from migrate.changeset.constraint import UniqueConstraint
from mediagoblin.db.extratypes import JSONEncoded, MutationDict
from mediagoblin.db.migration_tools import RegisterMigration, inspect_table
from mediagoblin.db.migration_tools import (RegisterMigration, inspect_table,
replace_table)
from mediagoblin.db.models import (MediaEntry, Collection, MediaComment, User,
Privilege)
@ -683,7 +684,7 @@ def create_moderation_tables(db):
db.commit()
# And then, once the information is taken from the is_admin & status columns
# And then, once the information is taken from is_admin & status columns
# we drop all of the vestigial columns from the User table.
#--------------------------------------------------------------------------
if db.bind.url.drivername == 'sqlite':
@ -694,25 +695,7 @@ def create_moderation_tables(db):
User_vR1.__table__.create(db.bind)
db.commit()
new_user_table = inspect_table(metadata, 'rename__users')
for row in db.execute(user_table.select()):
db.execute(new_user_table.insert().values(
username=row.username,
email=row.email,
pw_hash=row.pw_hash,
created=row.created,
wants_comment_notification=row.wants_comment_notification,
wants_notifications=row.wants_notifications,
license_preference=row.license_preference,
url=row.url,
bio=row.bio,
uploaded=row.uploaded,
upload_limit=row.upload_limit))
db.commit()
user_table.drop()
db.commit()
new_user_table.rename("core__users")
replace_table(db,user_table, new_user_table)
else:
# If the db is not run using SQLite, this process is much simpler ~~~~~