[LNT] r306361 - migrate: Redo session handling

Matthias Braun via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 26 21:11:32 PDT 2017


Author: matze
Date: Mon Jun 26 21:11:32 2017
New Revision: 306361

URL: http://llvm.org/viewvc/llvm-project?rev=306361&view=rev
Log:
migrate: Redo session handling

Rework the session handling as my previous close_all() failed on sqlite
in-memory databases. We only construct very short-lives sessions that
exactly update the schema versions in the database and get closed.

Modified:
    lnt/trunk/lnt/server/db/migrate.py

Modified: lnt/trunk/lnt/server/db/migrate.py
URL: http://llvm.org/viewvc/llvm-project/lnt/trunk/lnt/server/db/migrate.py?rev=306361&r1=306360&r2=306361&view=diff
==============================================================================
--- lnt/trunk/lnt/server/db/migrate.py (original)
+++ lnt/trunk/lnt/server/db/migrate.py Mon Jun 26 21:11:32 2017
@@ -113,7 +113,22 @@ def _load_migrations():
 
 logger = logging.getLogger(__name__)
 
-def update_schema(engine, session, versions, available_migrations, schema_name):
+def _set_schema_version(engine, schema_name, new_version):
+    # Keep the updating to a single transaction that is immediately committed.
+    session = sqlalchemy.orm.sessionmaker(engine)()
+    schema_version = session.query(SchemaVersion) \
+                            .filter(SchemaVersion.name == schema_name) \
+                            .first()
+    if schema_version is None:
+        schema_version = SchemaVersion(schema_name, new_version)
+    else:
+        schema_version.version = new_version
+    session.add(schema_version)
+    session.commit()
+    session.close()
+
+
+def update_schema(engine, versions, available_migrations, schema_name):
     schema_migrations = available_migrations[schema_name]
 
     # Get the current schema version.
@@ -124,49 +139,41 @@ def update_schema(engine, session, versi
     if db_version is None:
         logger.info("assigning initial version for schema %r",
                     schema_name)
-        db_version = SchemaVersion(schema_name, 0)
-        session.add(db_version)
-        session.commit()
+        _set_schema_version(engine, schema_name, 0)
+        db_version = 0
 
     # If we are up-to-date, do nothing.
-    if db_version.version == current_version:
+    if db_version == current_version:
         return False
 
     # Otherwise, update the database.
-    if db_version.version > current_version:
+    if db_version > current_version:
         logger.error("invalid schema %r version %r (greater than current)",
                      schema_name, db_version)
         return False
 
     logger.info("updating schema %r from version %r to current version %r",
-                schema_name, db_version.version, current_version)
-    while db_version.version < current_version:
+                schema_name, db_version, current_version)
+    while db_version < current_version:
         # Lookup the upgrade function for this version.
-        upgrade_script = schema_migrations[db_version.version]
+        upgrade_script = schema_migrations[db_version]
 
         globals = {}
         execfile(upgrade_script, globals)
         upgrade_method = globals['upgrade']
 
-        # Make sure we don't have any transactions lingering when executing
-        # the upgrade script.
-        session.close_all()
-
         # Execute the upgrade.
         #
         # FIXME: Backup the database here.
         #
         # FIXME: Execute this inside a transaction?
         logger.info("applying upgrade for version %d to %d" % (
-                db_version.version, db_version.version+1))
+                db_version, db_version+1))
         upgrade_method(engine)
 
         # Update the schema version.
-        db_version.version += 1
-        session.add(db_version)
-
-        # Commit the result.
-        session.commit()
+        db_version += 1
+        _set_schema_version(engine, schema_name, db_version)
 
     return True
 
@@ -178,9 +185,6 @@ def update(engine):
     # Load the available migrations.
     available_migrations = _load_migrations()
 
-    # Create a session for our queries.
-    session = sqlalchemy.orm.sessionmaker(engine)()
-
     def will_not_handle_error(e):
         message = e.orig.message
         if 'no such table' in message:
@@ -192,6 +196,7 @@ def update(engine):
     # Load all the information from the versions tables. We just do the query
     # and handle the exception if the table hasn't been defined yet (for
     # databases before versioning started).
+    session = sqlalchemy.orm.sessionmaker(engine)()
     try:
         version_list = session.query(SchemaVersion).all()
     except (sqlalchemy.exc.OperationalError,
@@ -204,20 +209,14 @@ def update(engine):
 
         # Create the SchemaVersion table.
         Base.metadata.create_all(engine)
-        session.commit()
-
-        # Certain databases like PostgreSQL use ``isolated''
-        # transactions, i.e., we will be unable to insert data. Thus
-        # to ensure that no matter the settings, i.e. whether or not
-        # autocommit is set, we create a new session.
-        session = sqlalchemy.orm.sessionmaker(engine)()
 
         version_list = []
-    versions = dict((v.name, v)
+    session.close()
+    versions = dict((v.name, v.version)
                     for v in version_list)
 
     # Update the core schema.
-    any_changed |= update_schema(engine, session, versions,
+    any_changed |= update_schema(engine, versions,
                                  available_migrations, '__core__')
 
     if any_changed:




More information about the llvm-commits mailing list