From a31f2c68f6a0b7eab894fde4a368e78f2864fae1 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Tue, 11 Mar 2014 22:34:35 +0200 Subject: [PATCH] Fix bug #1136278 by trying to detect that the upgrades have already been performed --- openlp/plugins/bibles/lib/upgrade.py | 49 ++++++++++++--------- openlp/plugins/songs/lib/upgrade.py | 58 ++++++++++++++++++------- openlp/plugins/songusage/lib/upgrade.py | 15 +++++-- 3 files changed, 81 insertions(+), 41 deletions(-) diff --git a/openlp/plugins/bibles/lib/upgrade.py b/openlp/plugins/bibles/lib/upgrade.py index 8598ed8ea..5d89018c3 100644 --- a/openlp/plugins/bibles/lib/upgrade.py +++ b/openlp/plugins/bibles/lib/upgrade.py @@ -37,6 +37,7 @@ from sqlalchemy import Table, func, select, insert __version__ = 1 log = logging.getLogger(__name__) + def upgrade_setup(metadata): """ Set up the latest revision all tables, with reflection, needed for the @@ -61,31 +62,37 @@ def upgrade_1(session, metadata, tables): metadata_table = metadata.tables[u'metadata'] # Copy "Version" to "name" ("version" used by upgrade system) # TODO: Clean up in a subsequent release of OpenLP (like 2.0 final) - session.execute(insert(metadata_table).values( - key=u'name', - value=select( - [metadata_table.c.value], - metadata_table.c.key == u'Version' - ).as_scalar() - )) + if select([metadata_table.c.value], metadata_table.c.key == u'Version')\ + .as_scalar().execute().fetchall(): + session.execute(insert(metadata_table).values( + key=u'name', + value=select( + [metadata_table.c.value], + metadata_table.c.key == u'Version' + ).as_scalar() + )) # Copy "Copyright" to "copyright" # TODO: Clean up in a subsequent release of OpenLP (like 2.0 final) - session.execute(insert(metadata_table).values( - key=u'copyright', - value=select( - [metadata_table.c.value], - metadata_table.c.key == u'Copyright' - ).as_scalar() - )) + if select([metadata_table.c.value], metadata_table.c.key == u'Copyright')\ + .as_scalar().execute().fetchall(): + session.execute(insert(metadata_table).values( + key=u'copyright', + value=select( + [metadata_table.c.value], + metadata_table.c.key == u'Copyright' + ).as_scalar() + )) # Copy "Permissions" to "permissions" # TODO: Clean up in a subsequent release of OpenLP (like 2.0 final) - session.execute(insert(metadata_table).values( - key=u'permissions', - value=select( - [metadata_table.c.value], - metadata_table.c.key == u'Permissions' - ).as_scalar() - )) + if select([metadata_table.c.value], metadata_table.c.key == u'Permissions')\ + .as_scalar().execute().fetchall(): + session.execute(insert(metadata_table).values( + key=u'permissions', + value=select( + [metadata_table.c.value], + metadata_table.c.key == u'Permissions' + ).as_scalar() + )) # Copy "Bookname language" to "book_name_language" # TODO: Clean up in a subsequent release of OpenLP (like 2.0 final) value_count = session.execute( diff --git a/openlp/plugins/songs/lib/upgrade.py b/openlp/plugins/songs/lib/upgrade.py index 02759f4ae..c99ec06fb 100644 --- a/openlp/plugins/songs/lib/upgrade.py +++ b/openlp/plugins/songs/lib/upgrade.py @@ -30,18 +30,24 @@ The :mod:`upgrade` module provides a way for the database and schema that is the backend for the Songs plugin """ +import logging from sqlalchemy import Column, Table, types +from sqlalchemy.exc import NoSuchTableError, OperationalError from sqlalchemy.sql.expression import func from migrate.changeset.constraint import ForeignKeyConstraint +log = logging.getLogger(__name__) __version__ = 3 + def upgrade_setup(metadata): """ Set up the latest revision all tables, with reflection, needed for the upgrade process. If you want to drop a table, you need to remove it from here, and add it to your upgrade function. + + :param metadata: The SQLAlchemy metadata object """ tables = { u'authors': Table(u'authors', metadata, autoload=True), @@ -66,16 +72,23 @@ def upgrade_1(session, metadata, tables): In order to facilitate this one-to-many relationship, a song_id column is added to the media_files table, and a weight column so that the media files can be ordered. + + :param session: An SQLAlchemy Session object + :param metadata: An SQLAlchemy MetaData object + :param tables: A dictionary of tables """ - Table(u'media_files_songs', metadata, autoload=True).drop(checkfirst=True) - Column(u'song_id', types.Integer(), default=None)\ - .create(table=tables[u'media_files']) - Column(u'weight', types.Integer(), default=0)\ - .create(table=tables[u'media_files']) - if metadata.bind.url.get_dialect().name != 'sqlite': - # SQLite doesn't support ALTER TABLE ADD CONSTRAINT - ForeignKeyConstraint([u'song_id'], [u'songs.id'], - table=tables[u'media_files']).create() + try: + Table(u'media_files_songs', metadata, autoload=True).drop(checkfirst=True) + Column(u'song_id', types.Integer(), default=None)\ + .create(table=tables[u'media_files']) + Column(u'weight', types.Integer(), default=0)\ + .create(table=tables[u'media_files']) + if metadata.bind.url.get_dialect().name != 'sqlite': + # SQLite doesn't support ALTER TABLE ADD CONSTRAINT + ForeignKeyConstraint([u'song_id'], [u'songs.id'], + table=tables[u'media_files']).create() + except (NoSuchTableError, OperationalError): + log.info(u'Upgrade 1 has already been run, continue with upgrade') def upgrade_2(session, metadata, tables): @@ -83,11 +96,18 @@ def upgrade_2(session, metadata, tables): Version 2 upgrade. This upgrade adds a create_date and last_modified date to the songs table + + :param session: An SQLAlchemy Session object + :param metadata: An SQLAlchemy MetaData object + :param tables: A dictionary of tables """ - Column(u'create_date', types.DateTime(), default=func.now())\ - .create(table=tables[u'songs']) - Column(u'last_modified', types.DateTime(), default=func.now())\ - .create(table=tables[u'songs']) + try: + Column(u'create_date', types.DateTime(), default=func.now())\ + .create(table=tables[u'songs']) + Column(u'last_modified', types.DateTime(), default=func.now())\ + .create(table=tables[u'songs']) + except OperationalError: + log.info(u'Upgrade 2 has already been run, continue with upgrade') def upgrade_3(session, metadata, tables): @@ -95,7 +115,13 @@ def upgrade_3(session, metadata, tables): Version 3 upgrade. This upgrade adds a temporary song flag to the songs table - """ - Column(u'temporary', types.Boolean(), default=False)\ - .create(table=tables[u'songs']) + :param session: An SQLAlchemy Session object + :param metadata: An SQLAlchemy MetaData object + :param tables: A dictionary of tables + """ + try: + Column(u'temporary', types.Boolean(), default=False)\ + .create(table=tables[u'songs']) + except OperationalError: + log.info(u'Upgrade 3 has already been run, continue with upgrade') diff --git a/openlp/plugins/songusage/lib/upgrade.py b/openlp/plugins/songusage/lib/upgrade.py index 8010f710b..c7cf778e8 100644 --- a/openlp/plugins/songusage/lib/upgrade.py +++ b/openlp/plugins/songusage/lib/upgrade.py @@ -30,11 +30,15 @@ The :mod:`upgrade` module provides a way for the database and schema that is the backend for the SongsUsage plugin """ +import logging from sqlalchemy import Column, Table, types +from sqlalchemy.exc import OperationalError +log = logging.getLogger(__name__) __version__ = 1 + def upgrade_setup(metadata): """ Set up the latest revision all tables, with reflection, needed for the @@ -53,7 +57,10 @@ def upgrade_1(session, metadata, tables): This upgrade adds two new fields to the songusage database """ - Column(u'plugin_name', types.Unicode(20), default=u'') \ - .create(table=tables[u'songusage_data'], populate_default=True) - Column(u'source', types.Unicode(10), default=u'') \ - .create(table=tables[u'songusage_data'], populate_default=True) + try: + Column(u'plugin_name', types.Unicode(20), default=u'') \ + .create(table=tables[u'songusage_data'], populate_default=True) + Column(u'source', types.Unicode(10), default=u'') \ + .create(table=tables[u'songusage_data'], populate_default=True) + except OperationalError: + log.info(u'Upgrade 1 has already been run, continue with upgrade')