|
a |
|
b/pyforge/flyway/command.py |
|
|
1 |
import logging
|
|
|
2 |
|
|
|
3 |
import pkg_resources
|
|
|
4 |
from pymongo.connection import Connection
|
|
|
5 |
from paste.script import command
|
|
|
6 |
|
|
|
7 |
from ming.datastore import DataStore
|
|
|
8 |
from ming.utils import parse_uri
|
|
|
9 |
|
|
|
10 |
class MigrateCommand(command.Command):
|
|
|
11 |
min_args = 0
|
|
|
12 |
group_name = 'Flyway'
|
|
|
13 |
summary = 'Migrate the Ming schema'
|
|
|
14 |
usage = 'NAME [options] [module=version...]'
|
|
|
15 |
entry_point_section='flyway.migrations'
|
|
|
16 |
parser = command.Command.standard_parser(verbose=True)
|
|
|
17 |
parser.add_option('-u', '--url', dest='connection_url',
|
|
|
18 |
default='mongo://127.0.0.1:27017/',
|
|
|
19 |
help='MongoDB url to migrate')
|
|
|
20 |
parser.add_option('-l', '--logging', dest='logging_config_file',
|
|
|
21 |
default=None)
|
|
|
22 |
parser.add_option('--log-level', dest='log_level', default='INFO')
|
|
|
23 |
parser.add_option('--reset', dest='reset', action='store_true', default=False)
|
|
|
24 |
parser.add_option('-d', '--dry-run', dest='dry_run', action='store_true', default=False)
|
|
|
25 |
|
|
|
26 |
def command(self):
|
|
|
27 |
self._setup_logging()
|
|
|
28 |
self._load_migrations()
|
|
|
29 |
from .runner import run_migration, reset_migration
|
|
|
30 |
parsed_connection_url = parse_uri(self.options.connection_url)
|
|
|
31 |
if not parsed_connection_url['path']:
|
|
|
32 |
parsed_connection_url['path'] += '/'
|
|
|
33 |
if parsed_connection_url['path'] == '/':
|
|
|
34 |
# Find all the databases managed by the server
|
|
|
35 |
connection = Connection(
|
|
|
36 |
parsed_connection_url['host'],
|
|
|
37 |
parsed_connection_url['port'])
|
|
|
38 |
databases = connection.database_names()
|
|
|
39 |
datastores = [ DataStore(self.options.connection_url + db)
|
|
|
40 |
for db in connection.database_names() ]
|
|
|
41 |
else:
|
|
|
42 |
datastores = [ DataStore(self.options.connection_url) ]
|
|
|
43 |
self.log.info('Migrate server: %s:%s',
|
|
|
44 |
parsed_connection_url['host'],
|
|
|
45 |
parsed_connection_url['port'])
|
|
|
46 |
for ds in datastores:
|
|
|
47 |
self.log.info('Migrate DB: %s', ds.database)
|
|
|
48 |
if self.options.reset:
|
|
|
49 |
reset_migration(ds, dry_run=self.options.dry_run)
|
|
|
50 |
else:
|
|
|
51 |
run_migration(ds, self._target_versions(), dry_run=self.options.dry_run)
|
|
|
52 |
|
|
|
53 |
def _setup_logging(self):
|
|
|
54 |
if self.options.logging_config_file:
|
|
|
55 |
logging.config.fileConfig(self.options.logging_config_file)
|
|
|
56 |
else:
|
|
|
57 |
logging.basicConfig(
|
|
|
58 |
level=logging._levelNames[self.options.log_level],
|
|
|
59 |
format='%(asctime)s,%(msecs)03d %(levelname)-5.5s'
|
|
|
60 |
' [%(name)s] %(message)s',
|
|
|
61 |
datefmt='%H:%M:%S')
|
|
|
62 |
self.log = logging.getLogger(__name__)
|
|
|
63 |
|
|
|
64 |
def _target_versions(self):
|
|
|
65 |
from .migrate import Migration
|
|
|
66 |
latest_versions = Migration.latest_versions()
|
|
|
67 |
if self.args:
|
|
|
68 |
target = {}
|
|
|
69 |
for a in self.args:
|
|
|
70 |
if '=' in a:
|
|
|
71 |
k,v = a.split('=')
|
|
|
72 |
target[k] = int(v)
|
|
|
73 |
else:
|
|
|
74 |
target[a] = latest_versions[a]
|
|
|
75 |
return target
|
|
|
76 |
else:
|
|
|
77 |
return latest_versions
|
|
|
78 |
|
|
|
79 |
def _load_migrations(self):
|
|
|
80 |
from .migrate import Migration
|
|
|
81 |
for ep in pkg_resources.iter_entry_points(self.entry_point_section):
|
|
|
82 |
self.log.debug('Loading migration module %s', ep.name)
|
|
|
83 |
Migration._current_migrations_module = ep.name
|
|
|
84 |
ep.load()
|
|
|
85 |
Migration._current_migrations_module = None
|