replacement_table.rename(old_table_name)
db.commit()
+
+def model_iteration_hack(db, query):
+ """
+ This will return either the query you gave if it's postgres or in the case
+ of sqlite it will return a list with all the results. This is because in
+ migrations it seems sqlite can't deal with concurrent quries so if you're
+ iterating over models and doing a commit inside the loop, you will run into
+ an exception which says you've closed the connection on your iteration
+ query. This fixes it.
+
+ NB: This loads all of the query reuslts into memeory, there isn't a good
+ way around this, we're assuming sqlite users have small databases.
+ """
+ # If it's SQLite just return all the objects
+ if db.bind.url.drivername == "sqlite":
+ return [obj for obj in db.execute(query)]
+
+ # Postgres return the query as it knows how to deal with it.
+ return db.execute(query)
+
+
from mediagoblin.tools import crypto
from mediagoblin.db.extratypes import JSONEncoded, MutationDict
from mediagoblin.db.migration_tools import (
- RegisterMigration, inspect_table, replace_table_hack)
+ RegisterMigration, inspect_table, replace_table_hack, model_iteration_hack)
from mediagoblin.db.models import (MediaEntry, Collection, Comment, User,
Privilege, Generator, LocalUser, Location,
Client, RequestToken, AccessToken)
ai_table = inspect_table(metadata, "core__activity_intermediators")
gmr_table = inspect_table(metadata, "core__generic_model_reference")
-
# Iterate through all activities doing the migration per activity.
- for activity in db.execute(activity_table.select()):
+ for activity in model_iteration_hack(db, activity_table.select()):
# First do the "Activity.object" migration to "Activity.temp_object"
# I need to get the object from the Activity, I can't use the old
# Activity.get_object as we're in a migration.
))
# Commit to the database. We're doing it here rather than outside the
- # loop because if the server has a lot of data this can cause problems.
+ # loop because if the server has a lot of data this can cause problems
db.commit()
@RegisterMigration(30, MIGRATIONS)
user_table = inspect_table(metadata, "core__users")
local_user_table = inspect_table(metadata, "core__local_users")
- for user in db.execute(user_table.select()):
+ for user in model_iteration_hack(db, user_table.select()):
db.execute(local_user_table.insert().values(
id=user.id,
username=user.username,
default=datetime.datetime.utcnow,
)
updated_column.create(media_entry_table)
+ db.commit()
# Data migration
- for entry in db.execute(media_entry_table.select()):
+ for entry in model_iteration_hack(db, media_entry_table.select()):
db.execute(media_entry_table.update().values(
updated=entry.created,
remote=False