From 7e572cd0c2dc8fee5b9c457e799ee22c777284cb Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Thu, 25 Aug 2011 11:02:59 +0200 Subject: [PATCH 1/6] Database upgrading, revision 1. --- openlp/core/lib/db.py | 55 +++++++++++++++++++++++-- openlp/plugins/songs/lib/db.py | 51 ++++++++++++----------- openlp/plugins/songs/lib/upgrade.py | 63 +++++++++++++++++++++++++++++ openlp/plugins/songs/songsplugin.py | 4 +- 4 files changed, 142 insertions(+), 31 deletions(-) create mode 100644 openlp/plugins/songs/lib/upgrade.py diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 41b445cd5..93cd293a5 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -31,9 +31,9 @@ import logging import os from PyQt4 import QtCore -from sqlalchemy import create_engine, MetaData +from sqlalchemy import Table, MetaData, Column, types, create_engine from sqlalchemy.exc import InvalidRequestError -from sqlalchemy.orm import scoped_session, sessionmaker +from sqlalchemy.orm import scoped_session, sessionmaker, mapper from sqlalchemy.pool import NullPool from openlp.core.utils import AppLocation, delete_file @@ -59,6 +59,42 @@ def init_db(url, auto_flush=True, auto_commit=False): autocommit=auto_commit, bind=engine)) return session, metadata + +def upgrade_db(url, upgrade): + """ + Upgrade a database. + + ``url`` + The url of the database to upgrade. + + ``upgrade`` + The python module that contains the upgrade instructions. + """ + session, metadata = init_db(url) + tables = upgrade.upgrade_setup(metadata) + metadata_table = Table(u'metadata', metadata, + Column(u'key', types.Unicode(64), primary_key=True), + Column(u'value', types.UnicodeText(), default=None) + ) + metadata_table.create(checkfirst=True) + mapper(Metadata, metadata_table) + version_meta = session.query(Metadata).get(u'version') + if version_meta is None: + version_meta = Metadata.populate(key=u'version', value=u'0') + version = 0 + else: + version = int(version_meta.value) + version += 1 + while hasattr(upgrade, u'upgrade_%d' % version): + log.debug(u'Running upgrade_%d', version) + do_upgrade = getattr(upgrade, u'upgrade_%d' % version) + if not do_upgrade(session, metadata, tables): + break + version += 1 + version_meta.value = unicode(version) + session.add(version_meta) + session.commit() + def delete_database(plugin_name, db_file_name=None): """ Remove a database file from the system. @@ -79,6 +115,7 @@ def delete_database(plugin_name, db_file_name=None): AppLocation.get_section_data_path(plugin_name), plugin_name) return delete_file(db_file_path) + class BaseModel(object): """ BaseModel provides a base object with a set of generic functions @@ -94,11 +131,18 @@ class BaseModel(object): return instance +class Metadata(BaseModel): + """ + Provides a class for the metadata table. + """ + pass + + class Manager(object): """ Provide generic object persistence management """ - def __init__(self, plugin_name, init_schema, db_file_name=None): + def __init__(self, plugin_name, init_schema, db_file_name=None, upgrade_schema=None): """ Runs the initialisation process that includes creating the connection to the database and the tables if they don't exist. @@ -109,6 +153,9 @@ class Manager(object): ``init_schema`` The init_schema function for this database + ``upgrade_schema`` + The upgrade_schema function for this database + ``db_file_name`` The file name to use for this database. Defaults to None resulting in the plugin_name being used. @@ -134,6 +181,8 @@ class Manager(object): unicode(settings.value(u'db hostname').toString()), unicode(settings.value(u'db database').toString())) settings.endGroup() + if upgrade_schema: + upgrade_schema(self.db_url) self.session = init_schema(self.db_url) def save_object(self, object_instance, commit=True): diff --git a/openlp/plugins/songs/lib/db.py b/openlp/plugins/songs/lib/db.py index c5c019c3c..f37aed29f 100644 --- a/openlp/plugins/songs/lib/db.py +++ b/openlp/plugins/songs/lib/db.py @@ -32,7 +32,8 @@ the Songs plugin from sqlalchemy import Column, ForeignKey, Table, types from sqlalchemy.orm import mapper, relation -from openlp.core.lib.db import BaseModel, init_db +from openlp.core.lib.db import BaseModel, init_db, upgrade_db +from openlp.plugins.songs.lib import upgrade class Author(BaseModel): """ @@ -70,6 +71,14 @@ class Topic(BaseModel): """ pass +def upgrade_schema(url): + """ + Upgrades the songs database. + + ``url`` + The database to upgrade + """ + upgrade_db(url, upgrade) def init_schema(url): """ @@ -111,10 +120,6 @@ def init_schema(url): * file_name * type - **media_files_songs Table** - * media_file_id - * song_id - **song_books Table** The *song_books* table holds a list of books that a congregation gets their songs from, or old hymnals now no longer used. This table has the @@ -162,7 +167,7 @@ def init_schema(url): # Definition of the "authors" table authors_table = Table(u'authors', metadata, - Column(u'id', types.Integer, primary_key=True), + Column(u'id', types.Integer(), primary_key=True), Column(u'first_name', types.Unicode(128)), Column(u'last_name', types.Unicode(128)), Column(u'display_name', types.Unicode(255), index=True, nullable=False) @@ -170,22 +175,25 @@ def init_schema(url): # Definition of the "media_files" table media_files_table = Table(u'media_files', metadata, - Column(u'id', types.Integer, primary_key=True), + Column(u'id', types.Integer(), primary_key=True), + Column(u'song_id', types.Integer(), ForeignKey(u'songs.id'), + default=None), Column(u'file_name', types.Unicode(255), nullable=False), - Column(u'type', types.Unicode(64), nullable=False, default=u'audio') + Column(u'type', types.Unicode(64), nullable=False, default=u'audio'), + Column(u'weight', types.Integer(), default=0) ) # Definition of the "song_books" table song_books_table = Table(u'song_books', metadata, - Column(u'id', types.Integer, primary_key=True), + Column(u'id', types.Integer(), primary_key=True), Column(u'name', types.Unicode(128), nullable=False), Column(u'publisher', types.Unicode(128)) ) # Definition of the "songs" table songs_table = Table(u'songs', metadata, - Column(u'id', types.Integer, primary_key=True), - Column(u'song_book_id', types.Integer, + Column(u'id', types.Integer(), primary_key=True), + Column(u'song_book_id', types.Integer(), ForeignKey(u'song_books.id'), default=None), Column(u'title', types.Unicode(255), nullable=False), Column(u'alternate_title', types.Unicode(255)), @@ -202,31 +210,23 @@ def init_schema(url): # Definition of the "topics" table topics_table = Table(u'topics', metadata, - Column(u'id', types.Integer, primary_key=True), + Column(u'id', types.Integer(), primary_key=True), Column(u'name', types.Unicode(128), index=True, nullable=False) ) # Definition of the "authors_songs" table authors_songs_table = Table(u'authors_songs', metadata, - Column(u'author_id', types.Integer, + Column(u'author_id', types.Integer(), ForeignKey(u'authors.id'), primary_key=True), - Column(u'song_id', types.Integer, - ForeignKey(u'songs.id'), primary_key=True) - ) - - # Definition of the "media_files_songs" table - media_files_songs_table = Table(u'media_files_songs', metadata, - Column(u'media_file_id', types.Integer, - ForeignKey(u'media_files.id'), primary_key=True), - Column(u'song_id', types.Integer, + Column(u'song_id', types.Integer(), ForeignKey(u'songs.id'), primary_key=True) ) # Definition of the "songs_topics" table songs_topics_table = Table(u'songs_topics', metadata, - Column(u'song_id', types.Integer, + Column(u'song_id', types.Integer(), ForeignKey(u'songs.id'), primary_key=True), - Column(u'topic_id', types.Integer, + Column(u'topic_id', types.Integer(), ForeignKey(u'topics.id'), primary_key=True) ) @@ -238,8 +238,7 @@ def init_schema(url): 'authors': relation(Author, backref='songs', secondary=authors_songs_table, lazy=False), 'book': relation(Book, backref='songs'), - 'media_files': relation(MediaFile, backref='songs', - secondary=media_files_songs_table), + 'media_files': relation(MediaFile, backref='songs'), 'topics': relation(Topic, backref='songs', secondary=songs_topics_table) }) diff --git a/openlp/plugins/songs/lib/upgrade.py b/openlp/plugins/songs/lib/upgrade.py new file mode 100644 index 000000000..09b7cc2e0 --- /dev/null +++ b/openlp/plugins/songs/lib/upgrade.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2011 Raoul Snyman # +# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan # +# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # +# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # +# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # +# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### +""" +The :mod:`upgrade` module provides a way for the database and schema that is the backend for +the Songs plugin +""" + +from sqlalchemy import Column, ForeignKey, Table, types +from migrate import changeset +from migrate.changeset.constraint import ForeignKeyConstraint + +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): + 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'], populate_default=True) + Column(u'weight', types.Integer(), default=0)\ + .create(table=tables[u'media_files'], populate_default=True) + if metadata.bind.url.get_dialect().name != 'sqlite': + ForeignKeyConstraint([u'song_id'], [u'songs.id'], + table=tables[u'media_files']).create() + return True \ No newline at end of file diff --git a/openlp/plugins/songs/songsplugin.py b/openlp/plugins/songs/songsplugin.py index 8a773be90..9fd113186 100644 --- a/openlp/plugins/songs/songsplugin.py +++ b/openlp/plugins/songs/songsplugin.py @@ -37,7 +37,7 @@ from openlp.core.lib.db import Manager from openlp.core.lib.ui import UiStrings, base_action, icon_action from openlp.core.utils.actions import ActionList from openlp.plugins.songs.lib import clean_song, SongMediaItem, SongsTab -from openlp.plugins.songs.lib.db import init_schema, Song +from openlp.plugins.songs.lib.db import init_schema, upgrade_schema, Song from openlp.plugins.songs.lib.importer import SongFormat from openlp.plugins.songs.lib.olpimport import OpenLPSongImport @@ -58,8 +58,8 @@ class SongsPlugin(Plugin): Create and set up the Songs plugin. """ Plugin.__init__(self, u'songs', plugin_helpers, SongMediaItem, SongsTab) + self.manager = Manager(u'songs', init_schema, upgrade_schema=upgrade_schema) self.weight = -10 - self.manager = Manager(u'songs', init_schema) self.icon_path = u':/plugins/plugin_songs.png' self.icon = build_icon(self.icon_path) From 923261c59c90bd54d1da72f6656612a31147ae87 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Thu, 25 Aug 2011 11:22:48 +0200 Subject: [PATCH 2/6] Even better, got rid of 'upgrade_schema' function which is not really needed. --- openlp/core/lib/db.py | 7 ++++--- openlp/plugins/songs/lib/db.py | 12 +----------- openlp/plugins/songs/songsplugin.py | 7 ++++--- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 93cd293a5..fab20d36f 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -142,7 +142,8 @@ class Manager(object): """ Provide generic object persistence management """ - def __init__(self, plugin_name, init_schema, db_file_name=None, upgrade_schema=None): + def __init__(self, plugin_name, init_schema, db_file_name=None, + upgrade_mod=None): """ Runs the initialisation process that includes creating the connection to the database and the tables if they don't exist. @@ -181,8 +182,8 @@ class Manager(object): unicode(settings.value(u'db hostname').toString()), unicode(settings.value(u'db database').toString())) settings.endGroup() - if upgrade_schema: - upgrade_schema(self.db_url) + if upgrade_mod: + upgrade_db(self.db_url, upgrade_mod) self.session = init_schema(self.db_url) def save_object(self, object_instance, commit=True): diff --git a/openlp/plugins/songs/lib/db.py b/openlp/plugins/songs/lib/db.py index f37aed29f..bee64b3ba 100644 --- a/openlp/plugins/songs/lib/db.py +++ b/openlp/plugins/songs/lib/db.py @@ -32,8 +32,7 @@ the Songs plugin from sqlalchemy import Column, ForeignKey, Table, types from sqlalchemy.orm import mapper, relation -from openlp.core.lib.db import BaseModel, init_db, upgrade_db -from openlp.plugins.songs.lib import upgrade +from openlp.core.lib.db import BaseModel, init_db class Author(BaseModel): """ @@ -71,15 +70,6 @@ class Topic(BaseModel): """ pass -def upgrade_schema(url): - """ - Upgrades the songs database. - - ``url`` - The database to upgrade - """ - upgrade_db(url, upgrade) - def init_schema(url): """ Setup the songs database connection and initialise the database schema. diff --git a/openlp/plugins/songs/songsplugin.py b/openlp/plugins/songs/songsplugin.py index 9fd113186..f2bf36790 100644 --- a/openlp/plugins/songs/songsplugin.py +++ b/openlp/plugins/songs/songsplugin.py @@ -36,8 +36,9 @@ from openlp.core.lib import Plugin, StringContent, build_icon, translate, \ from openlp.core.lib.db import Manager from openlp.core.lib.ui import UiStrings, base_action, icon_action from openlp.core.utils.actions import ActionList -from openlp.plugins.songs.lib import clean_song, SongMediaItem, SongsTab -from openlp.plugins.songs.lib.db import init_schema, upgrade_schema, Song +from openlp.plugins.songs.lib import clean_song, upgrade, SongMediaItem, \ + SongsTab +from openlp.plugins.songs.lib.db import init_schema, Song from openlp.plugins.songs.lib.importer import SongFormat from openlp.plugins.songs.lib.olpimport import OpenLPSongImport @@ -58,7 +59,7 @@ class SongsPlugin(Plugin): Create and set up the Songs plugin. """ Plugin.__init__(self, u'songs', plugin_helpers, SongMediaItem, SongsTab) - self.manager = Manager(u'songs', init_schema, upgrade_schema=upgrade_schema) + self.manager = Manager(u'songs', init_schema, upgrade_mod=upgrade) self.weight = -10 self.icon_path = u':/plugins/plugin_songs.png' self.icon = build_icon(self.icon_path) From ddf148449d253e7fdf541e7fedb69b657d793349 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Thu, 25 Aug 2011 13:47:07 +0200 Subject: [PATCH 3/6] Now with exception handling. --- openlp/core/lib/db.py | 13 ++++++++----- openlp/plugins/songs/lib/upgrade.py | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index fab20d36f..12f35ad1f 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -32,7 +32,7 @@ import os from PyQt4 import QtCore from sqlalchemy import Table, MetaData, Column, types, create_engine -from sqlalchemy.exc import InvalidRequestError +from sqlalchemy.exc import SQLAlchemyError, InvalidRequestError, DBAPIError from sqlalchemy.orm import scoped_session, sessionmaker, mapper from sqlalchemy.pool import NullPool @@ -87,11 +87,14 @@ def upgrade_db(url, upgrade): version += 1 while hasattr(upgrade, u'upgrade_%d' % version): log.debug(u'Running upgrade_%d', version) - do_upgrade = getattr(upgrade, u'upgrade_%d' % version) - if not do_upgrade(session, metadata, tables): + try: + getattr(upgrade, u'upgrade_%d' % version)(session, metadata, tables) + version += 1 + version_meta.value = unicode(version) + except SQLAlchemyError, DBAPIError: + log.exception(u'Could not run database upgrade script "upgrade_%s"'\ + ', upgrade process has been halted.', version) break - version += 1 - version_meta.value = unicode(version) session.add(version_meta) session.commit() diff --git a/openlp/plugins/songs/lib/upgrade.py b/openlp/plugins/songs/lib/upgrade.py index 09b7cc2e0..278b6fe86 100644 --- a/openlp/plugins/songs/lib/upgrade.py +++ b/openlp/plugins/songs/lib/upgrade.py @@ -60,4 +60,4 @@ def upgrade_1(session, metadata, tables): if metadata.bind.url.get_dialect().name != 'sqlite': ForeignKeyConstraint([u'song_id'], [u'songs.id'], table=tables[u'media_files']).create() - return True \ No newline at end of file + From ff7a7d734a76152ca6751ce7979e17254762cd32 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Thu, 25 Aug 2011 17:24:47 +0200 Subject: [PATCH 4/6] Added migrate dependency to deb package. --- resources/debian/debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/debian/debian/control b/resources/debian/debian/control index 220b500d2..423d81df0 100644 --- a/resources/debian/debian/control +++ b/resources/debian/debian/control @@ -11,7 +11,7 @@ Package: openlp Architecture: all Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, python-qt4, python-qt4-phonon, python-sqlalchemy, python-chardet, python-beautifulsoup, - python-lxml, python-sqlite, python-enchant + python-lxml, python-sqlite, python-enchant, python-migrate Conflicts: python-openlp Description: Church lyrics projection application OpenLP is free church presentation software, or lyrics projection software, From bcf9b174ff12cf9c4223c1964bb19ad7033066ee Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Thu, 25 Aug 2011 22:02:55 +0200 Subject: [PATCH 5/6] Fixed a bug where the version number saved to the database was incorrect. Added the ability to throw an error message and not load the database if the db is too new or incorrect. --- openlp/core/lib/db.py | 29 ++++++++++++++++++++++++++--- openlp/plugins/songs/lib/upgrade.py | 2 ++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 12f35ad1f..fb8a38b1f 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -36,6 +36,8 @@ from sqlalchemy.exc import SQLAlchemyError, InvalidRequestError, DBAPIError from sqlalchemy.orm import scoped_session, sessionmaker, mapper from sqlalchemy.pool import NullPool +from openlp.core.lib import translate +from openlp.core.lib.ui import critical_error_message_box from openlp.core.utils import AppLocation, delete_file log = logging.getLogger(__name__) @@ -84,19 +86,22 @@ def upgrade_db(url, upgrade): version = 0 else: version = int(version_meta.value) + if version > upgrade.__version__: + return version, upgrade.__version__ version += 1 while hasattr(upgrade, u'upgrade_%d' % version): log.debug(u'Running upgrade_%d', version) try: getattr(upgrade, u'upgrade_%d' % version)(session, metadata, tables) - version += 1 version_meta.value = unicode(version) except SQLAlchemyError, DBAPIError: log.exception(u'Could not run database upgrade script "upgrade_%s"'\ ', upgrade process has been halted.', version) break + version += 1 session.add(version_meta) session.commit() + return int(version_meta.value), upgrade.__version__ def delete_database(plugin_name, db_file_name=None): """ @@ -186,8 +191,26 @@ class Manager(object): unicode(settings.value(u'db database').toString())) settings.endGroup() if upgrade_mod: - upgrade_db(self.db_url, upgrade_mod) - self.session = init_schema(self.db_url) + db_ver, up_ver = upgrade_db(self.db_url, upgrade_mod) + if db_ver > up_ver: + critical_error_message_box( + translate('OpenLP.Manager', 'Database Error'), + unicode(translate('OpenLP.Manager', 'The database being ' + 'loaded was created in a more recent version of ' + 'OpenLP. The database is version %d, while OpenLP ' + 'expects version %d. The database will not be loaded.' + '\n\nDatabase: %s')) % \ + (db_ver, up_ver, self.db_url) + ) + return + try: + self.session = init_schema(self.db_url) + except: + critical_error_message_box( + translate('OpenLP.Manager', 'Database Error'), + unicode(translate('OpenLP.Manager', 'OpenLP cannot load your ' + 'database.\n\nDatabase: %s')) % self.db_url + ) def save_object(self, object_instance, commit=True): """ diff --git a/openlp/plugins/songs/lib/upgrade.py b/openlp/plugins/songs/lib/upgrade.py index 278b6fe86..56b04bb01 100644 --- a/openlp/plugins/songs/lib/upgrade.py +++ b/openlp/plugins/songs/lib/upgrade.py @@ -33,6 +33,8 @@ from sqlalchemy import Column, ForeignKey, Table, types from migrate import changeset from migrate.changeset.constraint import ForeignKeyConstraint +__version__ = 1 + def upgrade_setup(metadata): """ Set up the latest revision all tables, with reflection, needed for the From 4b1ce7102e48e2d71bc63a49f7f928903517cbb9 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Thu, 25 Aug 2011 22:14:02 +0200 Subject: [PATCH 6/6] A few more tweaks as requested by Andreas. --- openlp/plugins/songs/lib/upgrade.py | 12 ++++++++++++ scripts/check_dependencies.py | 7 ++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/openlp/plugins/songs/lib/upgrade.py b/openlp/plugins/songs/lib/upgrade.py index 56b04bb01..e0f2668d9 100644 --- a/openlp/plugins/songs/lib/upgrade.py +++ b/openlp/plugins/songs/lib/upgrade.py @@ -54,12 +54,24 @@ def upgrade_setup(metadata): def upgrade_1(session, metadata, tables): + """ + Version 1 upgrade. + + This upgrade removes the many-to-many relationship between songs and + media_files and replaces it with a one-to-many, which is far more + representative of the real relationship between the two entities. + + 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. + """ 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'], populate_default=True) Column(u'weight', types.Integer(), default=0)\ .create(table=tables[u'media_files'], populate_default=True) 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() diff --git a/scripts/check_dependencies.py b/scripts/check_dependencies.py index 7048ceeab..5f2e4c148 100755 --- a/scripts/check_dependencies.py +++ b/scripts/check_dependencies.py @@ -46,14 +46,14 @@ VERS = { 'sqlalchemy': '0.5', # pyenchant 1.6 required on Windows 'enchant': '1.6' if is_win else '1.3' - } +} # pywin32 WIN32_MODULES = [ 'win32com', 'win32ui', 'pywintypes', - ] +] MODULES = [ 'PyQt4', @@ -72,7 +72,8 @@ MODULES = [ 'enchant', 'BeautifulSoup', 'mako', - ] + 'migrate', +] OPTIONAL_MODULES = [