Switch to unified view

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