Migrated to Alembic (if you'll excuse the pun)

This commit is contained in:
Raoul Snyman 2013-04-03 21:46:41 +02:00
parent d42f64e044
commit d88e8a0b02
5 changed files with 37 additions and 89 deletions

View File

@ -38,6 +38,8 @@ from sqlalchemy import Table, MetaData, Column, types, create_engine
from sqlalchemy.exc import SQLAlchemyError, InvalidRequestError, DBAPIError, OperationalError
from sqlalchemy.orm import scoped_session, sessionmaker, mapper
from sqlalchemy.pool import NullPool
from alembic.migration import MigrationContext
from alembic.operations import Operations
from openlp.core.lib import translate, Settings
from openlp.core.lib.ui import critical_error_message_box
@ -65,6 +67,17 @@ def init_db(url, auto_flush=True, auto_commit=False):
return session, metadata
def get_upgrade_op(session):
"""
Create a migration context and an operations object for performing upgrades.
``session``
The SQLAlchemy session object.
"""
context = MigrationContext(session.bind.connect())
return Operations(context)
def upgrade_db(url, upgrade):
"""
Upgrade a database.
@ -82,13 +95,7 @@ def upgrade_db(url, upgrade):
Provides a class for the metadata table.
"""
pass
load_changes = False
tables = []
try:
tables = upgrade.upgrade_setup(metadata)
load_changes = True
except (SQLAlchemyError, DBAPIError):
pass
metadata_table = Table(u'metadata', metadata,
Column(u'key', types.Unicode(64), primary_key=True),
Column(u'value', types.UnicodeText(), default=None)
@ -105,22 +112,22 @@ def upgrade_db(url, upgrade):
if version > upgrade.__version__:
return version, upgrade.__version__
version += 1
if load_changes:
try:
while hasattr(upgrade, u'upgrade_%d' % version):
log.debug(u'Running upgrade_%d', version)
try:
upgrade_func = getattr(upgrade, u'upgrade_%d' % version)
upgrade_func(session, metadata, tables)
upgrade_func(session, metadata)
session.commit()
# Update the version number AFTER a commit so that we are sure the previous transaction happened
version_meta.value = unicode(version)
session.commit()
version += 1
except (SQLAlchemyError, DBAPIError):
log.exception(u'Could not run database upgrade script '
'"upgrade_%s", upgrade process has been halted.', version)
log.exception(u'Could not run database upgrade script "upgrade_%s", upgrade process has been halted.',
version)
break
else:
except (SQLAlchemyError, DBAPIError):
version_meta = Metadata.populate(key=u'version', value=int(upgrade.__version__))
session.commit()
return int(version_meta.value), upgrade.__version__

View File

@ -38,28 +38,13 @@ __version__ = 1
log = logging.getLogger(__name__)
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.
"""
# Don't define the "metadata" table, as the upgrade mechanism already
# defines it.
tables = {
u'book': Table(u'book', metadata, autoload=True),
u'verse': Table(u'verse', metadata, autoload=True)
}
return tables
def upgrade_1(session, metadata, tables):
def upgrade_1(session, metadata):
"""
Version 1 upgrade.
This upgrade renames a number of keys to a single naming convention.
"""
metadata_table = metadata.tables[u'metadata']
metadata_table = Table(u'metadata', metadata, autoload=True)
# 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(

View File

@ -31,39 +31,14 @@ The :mod:`upgrade` module provides a way for the database and schema that is the
backend for the Songs plugin
"""
from sqlalchemy import Column, Table, types
from sqlalchemy import Column, types
from sqlalchemy.sql.expression import func
#from migrate.changeset.constraint import ForeignKeyConstraint
from alembic.migration import MigrationContext
from alembic.operations import Operations
from openlp.core.lib.db import get_upgrade_op
__version__ = 3
def get_alembic_operation(session):
context = MigrationContext(session.bind.connect())
return Operations(context)
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.
"""
tables = {
u'authors': Table(u'authors', metadata, autoload=True),
u'media_files': Table(u'media_files', metadata, autoload=True),
u'song_books': Table(u'song_books', metadata, autoload=True),
u'songs': Table(u'songs', metadata, autoload=True),
u'topics': Table(u'topics', metadata, autoload=True),
u'authors_songs': Table(u'authors_songs', metadata, autoload=True),
u'songs_topics': Table(u'songs_topics', metadata, autoload=True)
}
return tables
def upgrade_1(session, metadata, tables):
def upgrade_1(session, metadata):
"""
Version 1 upgrade.
@ -75,14 +50,7 @@ def upgrade_1(session, metadata, tables):
added to the media_files table, and a weight column so that the media
files can be ordered.
"""
#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()
op = get_alembic_operation(session)
op = get_upgrade_op(session)
op.drop_table(u'media_files_songs')
op.add_column(u'media_files', Column(u'song_id', types.Integer(), default=None))
op.add_column(u'media_files', Column(u'weight', types.Integer(), default=0))
@ -91,26 +59,23 @@ def upgrade_1(session, metadata, tables):
op.create_foreign_key(u'fk_media_files_song_id', u'media_files', u'songs', [u'song_id', u'id'])
def upgrade_2(session, metadata, tables):
def upgrade_2(session, metadata):
"""
Version 2 upgrade.
This upgrade adds a create_date and last_modified date to the songs table
"""
#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'])
op = get_alembic_operation(session)
op = get_upgrade_op(session)
op.add_column(u'songs', Column(u'create_date', types.DateTime(), default=func.now()))
op.add_column(u'songs', Column(u'last_modified', types.DateTime(), default=func.now()))
def upgrade_3(session, metadata, tables):
def upgrade_3(session, metadata):
"""
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'])
op = get_alembic_operation(session)
op = get_upgrade_op(session)
op.add_column(u'songs', Column(u'temporary', types.Boolean(), default=False))

View File

@ -30,30 +30,19 @@
The :mod:`upgrade` module provides a way for the database and schema that is the
backend for the SongsUsage plugin
"""
from openlp.core.lib.db import get_upgrade_op
from sqlalchemy import Column, Table, types
from sqlalchemy import Column, types
__version__ = 1
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.
"""
tables = {
u'songusage_data': Table(u'songusage_data', metadata, autoload=True)
}
return tables
def upgrade_1(session, metadata, tables):
def upgrade_1(session, metadata):
"""
Version 1 upgrade.
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)
op = get_upgrade_op(session)
op.add_column(u'songusage_data', Column(u'plugin_name', types.Unicode(20), server_default=u''))
op.add_column(u'songusage_data', Column(u'source', types.Unicode(10), server_default=u''))

View File

@ -157,6 +157,8 @@ OpenLP (previously openlp.org) is free church presentation software, or lyrics p
zip_safe=False,
install_requires=[
# -*- Extra requirements: -*-
'sqlalchemy',
'alembic'
],
entry_points="""
# -*- Entry points: -*-