1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU Affero General Public License for more details.
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 from sqlalchemy
.orm
import sessionmaker
22 from mediagoblin
.db
.open import setup_connection_and_db_from_config
23 from mediagoblin
.db
.migration_tools
import MigrationManager
, AlembicMigrationManager
24 from mediagoblin
.init
import setup_global_and_app_config
25 from mediagoblin
.tools
.common
import import_component
27 _log
= logging
.getLogger(__name__
)
29 ## Let's not set the level as debug by default to avoid confusing users :)
30 # _log.setLevel(logging.DEBUG)
33 def dbupdate_parse_setup(subparser
):
37 class DatabaseData(object):
38 def __init__(self
, name
, models
, foundations
, migrations
):
41 self
.foundations
= foundations
42 self
.migrations
= migrations
44 def make_migration_manager(self
, session
):
45 return MigrationManager(
46 self
.name
, self
.models
, self
.foundations
, self
.migrations
, session
)
49 def gather_database_data(plugins
):
51 Gather all database data relevant to the extensions we have
52 installed so we can do migrations and table initialization.
54 Returns a list of DatabaseData objects.
59 from mediagoblin
.db
.models
import MODELS
as MAIN_MODELS
60 from mediagoblin
.db
.migrations
import MIGRATIONS
as MAIN_MIGRATIONS
61 from mediagoblin
.db
.models
import FOUNDATIONS
as MAIN_FOUNDATIONS
63 managed_dbdata
.append(
65 u
'__main__', MAIN_MODELS
, MAIN_FOUNDATIONS
, MAIN_MIGRATIONS
))
67 for plugin
in plugins
:
69 models
= import_component('{0}.models:MODELS'.format(plugin
))
70 except ImportError as exc
:
71 _log
.debug('No models found for {0}: {1}'.format(
76 except AttributeError as exc
:
77 _log
.warning('Could not find MODELS in {0}.models, have you \
78 forgotten to add it? ({1})'.format(plugin
, exc
))
82 migrations
= import_component('{0}.migrations:MIGRATIONS'.format(
84 except ImportError as exc
:
85 _log
.debug('No migrations found for {0}: {1}'.format(
90 except AttributeError as exc
:
91 _log
.debug('Could not find MIGRATIONS in {0}.migrations, have you \
92 forgotten to add it? ({1})'.format(plugin
, exc
))
96 foundations
= import_component('{0}.models:FOUNDATIONS'.format(plugin
))
97 except ImportError as exc
:
99 except AttributeError as exc
:
103 managed_dbdata
.append(
104 DatabaseData(plugin
, models
, foundations
, migrations
))
107 return managed_dbdata
110 def run_alembic_migrations(db
, app_config
, global_config
):
111 """Initializes a database and runs all Alembic migrations."""
112 Session
= sessionmaker(bind
=db
.engine
)
113 manager
= AlembicMigrationManager(Session())
114 manager
.init_or_migrate()
117 def run_dbupdate(app_config
, global_config
):
119 Initialize or migrate the database as specified by the config file.
121 Will also initialize or migrate all extensions (media types, and
122 in the future, plugins)
125 # Set up the database
126 db
= setup_connection_and_db_from_config(app_config
, migrations
=True)
128 run_all_migrations(db
, app_config
, global_config
)
130 # TODO: Make this happen regardless of python 2 or 3 once ensured
133 run_alembic_migrations(db
, app_config
, global_config
)
136 def run_all_migrations(db
, app_config
, global_config
):
138 Initializes or migrates a database that already has a
139 connection setup and also initializes or migrates all
140 extensions based on the config files.
142 It can be used to initialize an in-memory database for
145 # Gather information from all media managers / projects
146 dbdatas
= gather_database_data(
147 list(global_config
.get('plugins', {}).keys()))
149 Session
= sessionmaker(bind
=db
.engine
)
151 # Setup media managers for all dbdata, run init/migrate and print info
152 # For each component, create/migrate tables
153 for dbdata
in dbdatas
:
154 migration_manager
= dbdata
.make_migration_manager(Session())
155 migration_manager
.init_or_migrate()
159 global_config
, app_config
= setup_global_and_app_config(args
.conf_file
)
160 run_dbupdate(app_config
, global_config
)