use logging module for output, fixes #26

This commit is contained in:
iElectric 2009-07-08 23:57:15 +02:00
parent 67af81806d
commit 1c166845f8
16 changed files with 91 additions and 45 deletions

@ -1,6 +1,7 @@
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)
- 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.

@ -28,12 +28,14 @@
import sys
import inspect
import warnings
import logging
from migrate.versioning import (exceptions, repository, schema, version,
script as script_) # command name conflict
from migrate.versioning.util import catch_known_errors, construct_engine
log = logging.getLogger(__name__)
__all__ = [
'help',
'create',
@ -211,14 +213,14 @@ def test(url, repository, **opts):
script = repos.version(None).script()
# Upgrade
print "Upgrading...",
log.info("Upgrading...")
script.run(engine, 1)
print "done"
log.info("done")
print "Downgrading...",
log.info("Downgrading...")
script.run(engine, -1)
print "done"
print "Success"
log.info("done")
log.info("Success")
def version_control(url, repository, version=None, **opts):
@ -333,13 +335,13 @@ def _migrate(url, repository, version, upgrade, err, **opts):
changeset = schema.changeset(version)
for ver, change in changeset:
nextver = ver + changeset.step
print '%s -> %s... ' % (ver, nextver)
log.info('%s -> %s... ', ver, nextver)
if opts.get('preview_sql'):
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):
print change.source()
log.info(change.source())
elif opts.get('preview_py'):
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
funcname = upgrade and "upgrade" or "downgrade"
func = getattr(module, funcname)
print inspect.getsource(func)
log.info(inspect.getsource(func))
else:
schema.runchange(ver, change, changeset.step)
print 'done'
log.info('done')
def _migrate_version(schema, version, upgrade, err):

@ -1,5 +1,13 @@
"""Things that should be imported by all migrate packages"""
#__all__ = ['logging','log','databases','operations']
from logger import logging, log
from const import databases, operations
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,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 logging
import migrate
import sqlalchemy
log = logging.getLogger(__name__)
HEADER = """
## File autogenerated by genmodel.py

@ -4,12 +4,15 @@
import os
import shutil
import logging
from migrate.versioning import exceptions
from migrate.versioning.base import *
from migrate.versioning.util import KeyedInstance
log = logging.getLogger(__name__)
class Pathed(KeyedInstance):
"""
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"""
parent_path = self.__class__._parent_path(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)
def _init_child(self, child, path):

@ -4,6 +4,7 @@
import os
import shutil
import string
import logging
from pkg_resources import resource_string, resource_filename
from migrate.versioning import exceptions, script, version, pathed, cfgparse
@ -11,6 +12,8 @@ from migrate.versioning.template import template
from migrate.versioning.base import *
log = logging.getLogger(__name__)
class Changeset(dict):
"""A collection of changes to be applied to a database.
@ -67,13 +70,13 @@ class Repository(pathed.Pathed):
_versions = 'versions'
def __init__(self, path):
log.info('Loading repository %s...' % path)
log.debug('Loading repository %s...' % path)
self.verify(path)
super(Repository, self).__init__(path)
self.config = cfgparse.Config(os.path.join(self.path, self._config))
self.versions = version.Collection(os.path.join(self.path,
self._versions))
log.info('Repository %s loaded successfully' % path)
log.debug('Repository %s loaded successfully' % path)
log.debug('Config: %r' % self.config.to_dict())
@classmethod

@ -2,6 +2,7 @@
Database schema version management.
"""
import sys
import logging
from sqlalchemy import (Table, Column, MetaData, String, Text, Integer,
create_engine)
@ -15,6 +16,8 @@ from migrate.versioning.util import load_model
from migrate.versioning.version import VerNum
log = logging.getLogger(__name__)
class ControlledSchema(object):
"""A database under version control"""

@ -1,9 +1,14 @@
"""
Schema differencing support.
"""
import logging
import sqlalchemy
from migrate.changeset import SQLA_06
log = logging.getLogger(__name__)
def getDiffOfModelAgainstDatabase(model, conn, excludeTables=None):
"""
Return differences of model against database.

@ -1,10 +1,13 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
from migrate.versioning.base import log, operations
from migrate.versioning.base import operations
from migrate.versioning import pathed, exceptions
log = logging.getLogger(__name__)
class BaseScript(pathed.Pathed):
"""Base class for other types of scripts.
All scripts have the following properties:
@ -20,10 +23,10 @@ class BaseScript(pathed.Pathed):
""" # TODO: sphinxfy this and implement it correctly
def __init__(self, path):
log.info('Loading script %s...' % path)
log.debug('Loading script %s...' % path)
self.verify(path)
super(BaseScript, self).__init__(path)
log.info('Script %s loaded successfully' % path)
log.debug('Script %s loaded successfully' % path)
@classmethod
def verify(cls, path):

@ -1,8 +1,9 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import warnings
import shutil
import warnings
import logging
from StringIO import StringIO
import migrate
@ -12,6 +13,8 @@ from migrate.versioning.template import template
from migrate.versioning.script import base
from migrate.versioning.util import import_path, load_model, construct_engine
log = logging.getLogger(__name__)
__all__ = ['PythonScript']
class PythonScript(base.BaseScript):

@ -1,9 +1,12 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
from migrate.versioning.script import base
log = logging.getLogger(__name__)
class SqlScript(base.BaseScript):
"""A file containing plain SQL statements."""

@ -2,10 +2,12 @@
import sys
import inspect
import logging
from optparse import OptionParser, BadOptionError
from migrate.versioning.base import *
from migrate.versioning import api, exceptions
from migrate.versioning.base import *
from migrate.versioning.util import asbool
alias = dict(
@ -50,10 +52,14 @@ class PassiveOptionParser(OptionParser):
del rargs[0]
def main(argv=None, **kwargs):
"""kwargs are default options that can be overriden with passing
--some_option to cmdline
"""
"""Shell interface to :mod:`migrate.versioning.api`.
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:])
commands = list(api.__all__)
commands.sort()
@ -138,6 +144,17 @@ def main(argv=None, **kwargs):
# apply overrides
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
try:
num_defaults = len(f_defaults)
@ -153,7 +170,7 @@ def main(argv=None, **kwargs):
try:
ret = command_func(**kwargs)
if ret is not None:
print ret
log.info(ret)
except (exceptions.UsageError, exceptions.KnownError), e:
parser.error(e.args[0])

@ -4,10 +4,13 @@
import os
import re
import shutil
import logging
from migrate.versioning import exceptions, pathed, script
log = logging.getLogger(__name__)
class VerNum(object):
"""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.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):
"""Test main() function"""
# TODO: test output?