Fix various style issues
[mediagoblin.git] / mediagoblin / gmg_commands / dbupdate.py
CommitLineData
70b44584 1# GNU MediaGoblin -- federated, autonomous media hosting
3ea1cf36 2# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
70b44584
CAW
3#
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.
8#
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.
13#
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/>.
16
f46e2a4d
JW
17import logging
18
c2059c4a 19import six
3ea1cf36
CAW
20from sqlalchemy.orm import sessionmaker
21
6eddc3b7 22from mediagoblin.db.open import setup_connection_and_db_from_config
2064ad94 23from mediagoblin.db.migration_tools import MigrationManager, AlembicMigrationManager
70b44584
CAW
24from mediagoblin.init import setup_global_and_app_config
25from mediagoblin.tools.common import import_component
26
f46e2a4d
JW
27_log = logging.getLogger(__name__)
28logging.basicConfig()
7468c390
CAW
29## Let's not set the level as debug by default to avoid confusing users :)
30# _log.setLevel(logging.DEBUG)
70b44584 31
70b44584 32
3ea1cf36
CAW
33def dbupdate_parse_setup(subparser):
34 pass
35
36
70b44584 37class DatabaseData(object):
08cd10d8 38 def __init__(self, name, models, foundations, migrations):
70b44584
CAW
39 self.name = name
40 self.models = models
08cd10d8 41 self.foundations = foundations
70b44584
CAW
42 self.migrations = migrations
43
3ea1cf36 44 def make_migration_manager(self, session):
70b44584 45 return MigrationManager(
08cd10d8 46 self.name, self.models, self.foundations, self.migrations, session)
70b44584
CAW
47
48
58a94757 49def gather_database_data(plugins):
70b44584 50 """
8da8c0ac
BB
51 Gather all database data relevant to the extensions installed.
52
70b44584
CAW
53 Gather all database data relevant to the extensions we have
54 installed so we can do migrations and table initialization.
55
56 Returns a list of DatabaseData objects.
57 """
58 managed_dbdata = []
59
60 # Add main first
b0c8328e 61 from mediagoblin.db.models import MODELS as MAIN_MODELS
95369884 62 from mediagoblin.db.migrations import MIGRATIONS as MAIN_MIGRATIONS
08cd10d8 63 from mediagoblin.db.models import FOUNDATIONS as MAIN_FOUNDATIONS
70b44584
CAW
64
65 managed_dbdata.append(
66 DatabaseData(
08cd10d8 67 u'__main__', MAIN_MODELS, MAIN_FOUNDATIONS, MAIN_MIGRATIONS))
70b44584 68
f46e2a4d
JW
69 for plugin in plugins:
70 try:
71 models = import_component('{0}.models:MODELS'.format(plugin))
72 except ImportError as exc:
73 _log.debug('No models found for {0}: {1}'.format(
74 plugin,
75 exc))
76
77 models = []
78 except AttributeError as exc:
8da8c0ac
BB
79 _log.warning('Could not find MODELS in {0}.models, have you '
80 'forgotten to add it? ({1})'.format(plugin, exc))
0ae38290 81 models = []
f46e2a4d
JW
82
83 try:
84 migrations = import_component('{0}.migrations:MIGRATIONS'.format(
85 plugin))
86 except ImportError as exc:
87 _log.debug('No migrations found for {0}: {1}'.format(
88 plugin,
89 exc))
90
91 migrations = {}
92 except AttributeError as exc:
8da8c0ac
BB
93 _log.debug('Could not find MIGRATIONS in {0}.migrations, have you'
94 'forgotten to add it? ({1})'.format(plugin, exc))
0ae38290 95 migrations = {}
f46e2a4d 96
08cd10d8 97 try:
8da8c0ac
BB
98 foundations = import_component(
99 '{0}.models:FOUNDATIONS'.format(plugin))
08cd10d8 100 except ImportError as exc:
31de493e 101 foundations = {}
08cd10d8 102 except AttributeError as exc:
08cd10d8 103 foundations = {}
104
f46e2a4d
JW
105 if models:
106 managed_dbdata.append(
8da8c0ac 107 DatabaseData(plugin, models, foundations, migrations))
f46e2a4d 108
70b44584
CAW
109 return managed_dbdata
110
111
65f20ca4 112def run_alembic_migrations(db, app_config, global_config):
8da8c0ac 113 """Initialize a database and runs all Alembic migrations."""
65f20ca4
BP
114 Session = sessionmaker(bind=db.engine)
115 manager = AlembicMigrationManager(Session())
116 manager.init_or_migrate()
117
118
f46e2a4d 119def run_dbupdate(app_config, global_config):
70b44584
CAW
120 """
121 Initialize or migrate the database as specified by the config file.
122
123 Will also initialize or migrate all extensions (media types, and
124 in the future, plugins)
125 """
4a698535
EL
126 # Set up the database
127 db = setup_connection_and_db_from_config(app_config, migrations=True)
4930c2ad 128 # Run the migrations
4a698535 129 run_all_migrations(db, app_config, global_config)
c2059c4a
CAW
130
131 # TODO: Make this happen regardless of python 2 or 3 once ensured
132 # to be "safe"!
133 if six.PY3:
134 run_alembic_migrations(db, app_config, global_config)
4a698535
EL
135
136
137def run_all_migrations(db, app_config, global_config):
8da8c0ac
BB
138 """Initialize or migrates a database.
139
31de493e 140 Initializes or migrates a database that already has a
6db23bd9
EL
141 connection setup and also initializes or migrates all
142 extensions based on the config files.
143
144 It can be used to initialize an in-memory database for
145 testing.
4a698535 146 """
70b44584 147 # Gather information from all media managers / projects
f46e2a4d 148 dbdatas = gather_database_data(
8da8c0ac 149 list(global_config.get('plugins', {}).keys()))
70b44584 150
3ea1cf36 151 Session = sessionmaker(bind=db.engine)
70b44584
CAW
152
153 # Setup media managers for all dbdata, run init/migrate and print info
154 # For each component, create/migrate tables
155 for dbdata in dbdatas:
3ea1cf36 156 migration_manager = dbdata.make_migration_manager(Session())
70b44584 157 migration_manager.init_or_migrate()
d693f6bd
CAW
158
159
160def dbupdate(args):
161 global_config, app_config = setup_global_and_app_config(args.conf_file)
f46e2a4d 162 run_dbupdate(app_config, global_config)