use logging module for output, fixes #26
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
0.5.5
|
0.5.5
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
- use Python logging for output, can be shut down by passing ``logging=False`` to :func:`migrate.versioning.shell.main`
|
||||||
- `url` parameter can also be an :class:`Engine` instance (this usage is discouraged though sometimes necessary)
|
- `url` parameter can also be an :class:`Engine` instance (this usage is discouraged though sometimes necessary)
|
||||||
- added support for SQLAlchemy 0.6 (missing oracle and firebird) by Michael Bayer
|
- added support for SQLAlchemy 0.6 (missing oracle and firebird) by Michael Bayer
|
||||||
- alter, create, drop column / rename table / rename index constructs now accept `alter_metadata` parameter. If True, it will modify Column/Table objects according to changes. Otherwise, everything will be untouched.
|
- alter, create, drop column / rename table / rename index constructs now accept `alter_metadata` parameter. If True, it will modify Column/Table objects according to changes. Otherwise, everything will be untouched.
|
||||||
|
@@ -28,12 +28,14 @@
|
|||||||
import sys
|
import sys
|
||||||
import inspect
|
import inspect
|
||||||
import warnings
|
import warnings
|
||||||
|
import logging
|
||||||
|
|
||||||
from migrate.versioning import (exceptions, repository, schema, version,
|
from migrate.versioning import (exceptions, repository, schema, version,
|
||||||
script as script_) # command name conflict
|
script as script_) # command name conflict
|
||||||
from migrate.versioning.util import catch_known_errors, construct_engine
|
from migrate.versioning.util import catch_known_errors, construct_engine
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'help',
|
'help',
|
||||||
'create',
|
'create',
|
||||||
@@ -211,14 +213,14 @@ def test(url, repository, **opts):
|
|||||||
script = repos.version(None).script()
|
script = repos.version(None).script()
|
||||||
|
|
||||||
# Upgrade
|
# Upgrade
|
||||||
print "Upgrading...",
|
log.info("Upgrading...")
|
||||||
script.run(engine, 1)
|
script.run(engine, 1)
|
||||||
print "done"
|
log.info("done")
|
||||||
|
|
||||||
print "Downgrading...",
|
log.info("Downgrading...")
|
||||||
script.run(engine, -1)
|
script.run(engine, -1)
|
||||||
print "done"
|
log.info("done")
|
||||||
print "Success"
|
log.info("Success")
|
||||||
|
|
||||||
|
|
||||||
def version_control(url, repository, version=None, **opts):
|
def version_control(url, repository, version=None, **opts):
|
||||||
@@ -333,13 +335,13 @@ def _migrate(url, repository, version, upgrade, err, **opts):
|
|||||||
changeset = schema.changeset(version)
|
changeset = schema.changeset(version)
|
||||||
for ver, change in changeset:
|
for ver, change in changeset:
|
||||||
nextver = ver + changeset.step
|
nextver = ver + changeset.step
|
||||||
print '%s -> %s... ' % (ver, nextver)
|
log.info('%s -> %s... ', ver, nextver)
|
||||||
|
|
||||||
if opts.get('preview_sql'):
|
if opts.get('preview_sql'):
|
||||||
if isinstance(change, PythonScript):
|
if isinstance(change, PythonScript):
|
||||||
print change.preview_sql(url, changeset.step, **opts)
|
log.info(change.preview_sql(url, changeset.step, **opts))
|
||||||
elif isinstance(change, SqlScript):
|
elif isinstance(change, SqlScript):
|
||||||
print change.source()
|
log.info(change.source())
|
||||||
|
|
||||||
elif opts.get('preview_py'):
|
elif opts.get('preview_py'):
|
||||||
if not isinstance(change, PythonScript):
|
if not isinstance(change, PythonScript):
|
||||||
@@ -349,10 +351,10 @@ def _migrate(url, repository, version, upgrade, err, **opts):
|
|||||||
module = schema.repository.version(source_ver).script().module
|
module = schema.repository.version(source_ver).script().module
|
||||||
funcname = upgrade and "upgrade" or "downgrade"
|
funcname = upgrade and "upgrade" or "downgrade"
|
||||||
func = getattr(module, funcname)
|
func = getattr(module, funcname)
|
||||||
print inspect.getsource(func)
|
log.info(inspect.getsource(func))
|
||||||
else:
|
else:
|
||||||
schema.runchange(ver, change, changeset.step)
|
schema.runchange(ver, change, changeset.step)
|
||||||
print 'done'
|
log.info('done')
|
||||||
|
|
||||||
|
|
||||||
def _migrate_version(schema, version, upgrade, err):
|
def _migrate_version(schema, version, upgrade, err):
|
||||||
|
@@ -1,5 +1,13 @@
|
|||||||
"""Things that should be imported by all migrate packages"""
|
"""Things that should be imported by all migrate packages"""
|
||||||
|
|
||||||
#__all__ = ['logging','log','databases','operations']
|
from sqlalchemy.util import OrderedDict
|
||||||
from logger import logging, log
|
|
||||||
from const import databases, operations
|
|
||||||
|
__all__ = ['databases', 'operations']
|
||||||
|
|
||||||
|
databases = ('sqlite', 'postgres', 'mysql', 'oracle', 'mssql', 'firebird')
|
||||||
|
|
||||||
|
# Map operation names to function names
|
||||||
|
operations = OrderedDict()
|
||||||
|
operations['upgrade'] = 'upgrade'
|
||||||
|
operations['downgrade'] = 'downgrade'
|
||||||
|
@@ -1,11 +0,0 @@
|
|||||||
from sqlalchemy.util import OrderedDict
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['databases', 'operations']
|
|
||||||
|
|
||||||
databases = ('sqlite', 'postgres', 'mysql', 'oracle', 'mssql', 'firebird')
|
|
||||||
|
|
||||||
# Map operation names to function names
|
|
||||||
operations = OrderedDict()
|
|
||||||
operations['upgrade'] = 'upgrade'
|
|
||||||
operations['downgrade'] = 'downgrade'
|
|
@@ -1,9 +0,0 @@
|
|||||||
"""Manages logging (to stdout) for our versioning system.
|
|
||||||
"""
|
|
||||||
import logging
|
|
||||||
|
|
||||||
log=logging.getLogger('migrate.versioning')
|
|
||||||
log.setLevel(logging.WARNING)
|
|
||||||
log.addHandler(logging.StreamHandler())
|
|
||||||
|
|
||||||
__all__ = ['log','logging']
|
|
@@ -7,11 +7,13 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
import logging
|
||||||
|
|
||||||
import migrate
|
import migrate
|
||||||
import sqlalchemy
|
import sqlalchemy
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
HEADER = """
|
HEADER = """
|
||||||
## File autogenerated by genmodel.py
|
## File autogenerated by genmodel.py
|
||||||
|
|
||||||
|
@@ -4,12 +4,15 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
import logging
|
||||||
|
|
||||||
from migrate.versioning import exceptions
|
from migrate.versioning import exceptions
|
||||||
from migrate.versioning.base import *
|
from migrate.versioning.base import *
|
||||||
from migrate.versioning.util import KeyedInstance
|
from migrate.versioning.util import KeyedInstance
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
class Pathed(KeyedInstance):
|
class Pathed(KeyedInstance):
|
||||||
"""
|
"""
|
||||||
A class associated with a path/directory tree.
|
A class associated with a path/directory tree.
|
||||||
@@ -32,7 +35,7 @@ class Pathed(KeyedInstance):
|
|||||||
"""Try to initialize this object's parent, if it has one"""
|
"""Try to initialize this object's parent, if it has one"""
|
||||||
parent_path = self.__class__._parent_path(path)
|
parent_path = self.__class__._parent_path(path)
|
||||||
self.parent = self.__class__.parent(parent_path)
|
self.parent = self.__class__.parent(parent_path)
|
||||||
log.info("Getting parent %r:%r" % (self.__class__.parent, parent_path))
|
log.debug("Getting parent %r:%r" % (self.__class__.parent, parent_path))
|
||||||
self.parent._init_child(path, self)
|
self.parent._init_child(path, self)
|
||||||
|
|
||||||
def _init_child(self, child, path):
|
def _init_child(self, child, path):
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import string
|
import string
|
||||||
|
import logging
|
||||||
from pkg_resources import resource_string, resource_filename
|
from pkg_resources import resource_string, resource_filename
|
||||||
|
|
||||||
from migrate.versioning import exceptions, script, version, pathed, cfgparse
|
from migrate.versioning import exceptions, script, version, pathed, cfgparse
|
||||||
@@ -11,6 +12,8 @@ from migrate.versioning.template import template
|
|||||||
from migrate.versioning.base import *
|
from migrate.versioning.base import *
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
class Changeset(dict):
|
class Changeset(dict):
|
||||||
"""A collection of changes to be applied to a database.
|
"""A collection of changes to be applied to a database.
|
||||||
|
|
||||||
@@ -67,13 +70,13 @@ class Repository(pathed.Pathed):
|
|||||||
_versions = 'versions'
|
_versions = 'versions'
|
||||||
|
|
||||||
def __init__(self, path):
|
def __init__(self, path):
|
||||||
log.info('Loading repository %s...' % path)
|
log.debug('Loading repository %s...' % path)
|
||||||
self.verify(path)
|
self.verify(path)
|
||||||
super(Repository, self).__init__(path)
|
super(Repository, self).__init__(path)
|
||||||
self.config = cfgparse.Config(os.path.join(self.path, self._config))
|
self.config = cfgparse.Config(os.path.join(self.path, self._config))
|
||||||
self.versions = version.Collection(os.path.join(self.path,
|
self.versions = version.Collection(os.path.join(self.path,
|
||||||
self._versions))
|
self._versions))
|
||||||
log.info('Repository %s loaded successfully' % path)
|
log.debug('Repository %s loaded successfully' % path)
|
||||||
log.debug('Config: %r' % self.config.to_dict())
|
log.debug('Config: %r' % self.config.to_dict())
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
Database schema version management.
|
Database schema version management.
|
||||||
"""
|
"""
|
||||||
import sys
|
import sys
|
||||||
|
import logging
|
||||||
|
|
||||||
from sqlalchemy import (Table, Column, MetaData, String, Text, Integer,
|
from sqlalchemy import (Table, Column, MetaData, String, Text, Integer,
|
||||||
create_engine)
|
create_engine)
|
||||||
@@ -15,6 +16,8 @@ from migrate.versioning.util import load_model
|
|||||||
from migrate.versioning.version import VerNum
|
from migrate.versioning.version import VerNum
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
class ControlledSchema(object):
|
class ControlledSchema(object):
|
||||||
"""A database under version control"""
|
"""A database under version control"""
|
||||||
|
|
||||||
|
@@ -1,9 +1,14 @@
|
|||||||
"""
|
"""
|
||||||
Schema differencing support.
|
Schema differencing support.
|
||||||
"""
|
"""
|
||||||
|
import logging
|
||||||
|
|
||||||
import sqlalchemy
|
import sqlalchemy
|
||||||
from migrate.changeset import SQLA_06
|
from migrate.changeset import SQLA_06
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
def getDiffOfModelAgainstDatabase(model, conn, excludeTables=None):
|
def getDiffOfModelAgainstDatabase(model, conn, excludeTables=None):
|
||||||
"""
|
"""
|
||||||
Return differences of model against database.
|
Return differences of model against database.
|
||||||
|
@@ -1,10 +1,13 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import logging
|
||||||
|
|
||||||
from migrate.versioning.base import log, operations
|
from migrate.versioning.base import operations
|
||||||
from migrate.versioning import pathed, exceptions
|
from migrate.versioning import pathed, exceptions
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
class BaseScript(pathed.Pathed):
|
class BaseScript(pathed.Pathed):
|
||||||
"""Base class for other types of scripts.
|
"""Base class for other types of scripts.
|
||||||
All scripts have the following properties:
|
All scripts have the following properties:
|
||||||
@@ -20,10 +23,10 @@ class BaseScript(pathed.Pathed):
|
|||||||
""" # TODO: sphinxfy this and implement it correctly
|
""" # TODO: sphinxfy this and implement it correctly
|
||||||
|
|
||||||
def __init__(self, path):
|
def __init__(self, path):
|
||||||
log.info('Loading script %s...' % path)
|
log.debug('Loading script %s...' % path)
|
||||||
self.verify(path)
|
self.verify(path)
|
||||||
super(BaseScript, self).__init__(path)
|
super(BaseScript, self).__init__(path)
|
||||||
log.info('Script %s loaded successfully' % path)
|
log.debug('Script %s loaded successfully' % path)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def verify(cls, path):
|
def verify(cls, path):
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import warnings
|
|
||||||
import shutil
|
import shutil
|
||||||
|
import warnings
|
||||||
|
import logging
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
|
|
||||||
import migrate
|
import migrate
|
||||||
@@ -12,6 +13,8 @@ from migrate.versioning.template import template
|
|||||||
from migrate.versioning.script import base
|
from migrate.versioning.script import base
|
||||||
from migrate.versioning.util import import_path, load_model, construct_engine
|
from migrate.versioning.util import import_path, load_model, construct_engine
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
__all__ = ['PythonScript']
|
__all__ = ['PythonScript']
|
||||||
|
|
||||||
class PythonScript(base.BaseScript):
|
class PythonScript(base.BaseScript):
|
||||||
|
@@ -1,9 +1,12 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import logging
|
||||||
|
|
||||||
from migrate.versioning.script import base
|
from migrate.versioning.script import base
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
class SqlScript(base.BaseScript):
|
class SqlScript(base.BaseScript):
|
||||||
"""A file containing plain SQL statements."""
|
"""A file containing plain SQL statements."""
|
||||||
|
|
||||||
|
@@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
import inspect
|
import inspect
|
||||||
|
import logging
|
||||||
from optparse import OptionParser, BadOptionError
|
from optparse import OptionParser, BadOptionError
|
||||||
|
|
||||||
from migrate.versioning.base import *
|
|
||||||
from migrate.versioning import api, exceptions
|
from migrate.versioning import api, exceptions
|
||||||
|
from migrate.versioning.base import *
|
||||||
|
from migrate.versioning.util import asbool
|
||||||
|
|
||||||
|
|
||||||
alias = dict(
|
alias = dict(
|
||||||
@@ -50,10 +52,14 @@ class PassiveOptionParser(OptionParser):
|
|||||||
del rargs[0]
|
del rargs[0]
|
||||||
|
|
||||||
def main(argv=None, **kwargs):
|
def main(argv=None, **kwargs):
|
||||||
"""kwargs are default options that can be overriden with passing
|
"""Shell interface to :mod:`migrate.versioning.api`.
|
||||||
--some_option to cmdline
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
kwargs are default options that can be overriden with passing
|
||||||
|
--some_option as command line option
|
||||||
|
|
||||||
|
:param logging: Let migrate configure logging
|
||||||
|
:type logging: bool
|
||||||
|
"""
|
||||||
argv = argv or list(sys.argv[1:])
|
argv = argv or list(sys.argv[1:])
|
||||||
commands = list(api.__all__)
|
commands = list(api.__all__)
|
||||||
commands.sort()
|
commands.sort()
|
||||||
@@ -138,6 +144,17 @@ def main(argv=None, **kwargs):
|
|||||||
# apply overrides
|
# apply overrides
|
||||||
kwargs.update(override_kwargs)
|
kwargs.update(override_kwargs)
|
||||||
|
|
||||||
|
# configure logging
|
||||||
|
if asbool(kwargs.pop('logging', True)):
|
||||||
|
logger = logging.getLogger()
|
||||||
|
logger.setLevel(logging.INFO)
|
||||||
|
formatter = logging.Formatter("%(message)s")
|
||||||
|
ch = logging.StreamHandler(sys.stdout)
|
||||||
|
ch.setFormatter(formatter)
|
||||||
|
logger.addHandler(ch)
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
# check if all args are given
|
# check if all args are given
|
||||||
try:
|
try:
|
||||||
num_defaults = len(f_defaults)
|
num_defaults = len(f_defaults)
|
||||||
@@ -153,7 +170,7 @@ def main(argv=None, **kwargs):
|
|||||||
try:
|
try:
|
||||||
ret = command_func(**kwargs)
|
ret = command_func(**kwargs)
|
||||||
if ret is not None:
|
if ret is not None:
|
||||||
print ret
|
log.info(ret)
|
||||||
except (exceptions.UsageError, exceptions.KnownError), e:
|
except (exceptions.UsageError, exceptions.KnownError), e:
|
||||||
parser.error(e.args[0])
|
parser.error(e.args[0])
|
||||||
|
|
||||||
|
@@ -4,10 +4,13 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
|
import logging
|
||||||
|
|
||||||
from migrate.versioning import exceptions, pathed, script
|
from migrate.versioning import exceptions, pathed, script
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
class VerNum(object):
|
class VerNum(object):
|
||||||
"""A version number that behaves like a string and int at the same time"""
|
"""A version number that behaves like a string and int at the same time"""
|
||||||
|
|
||||||
|
@@ -31,6 +31,16 @@ class TestShellCommands(Shell):
|
|||||||
self.assertTrue(result.stdout)
|
self.assertTrue(result.stdout)
|
||||||
self.assertFalse(result.stderr)
|
self.assertFalse(result.stderr)
|
||||||
|
|
||||||
|
def test_shutdown_logging(self):
|
||||||
|
"""Try to shutdown logging output"""
|
||||||
|
repos = self.tmp_repos()
|
||||||
|
result = self.env.run('migrate create %s repository_name' % repos)
|
||||||
|
result = self.env.run('migrate version %s --logging=False' % repos)
|
||||||
|
self.assertEqual(result.stdout, '')
|
||||||
|
|
||||||
|
# TODO: assert logging messages to 0
|
||||||
|
shell.main(['version', repos], logging=False)
|
||||||
|
|
||||||
def test_main(self):
|
def test_main(self):
|
||||||
"""Test main() function"""
|
"""Test main() function"""
|
||||||
# TODO: test output?
|
# TODO: test output?
|
||||||
|
Reference in New Issue
Block a user