Changeset - cd2103a83487
[Not reviewed]
default
0 1 0
timeless@gmail.com - 10 years ago 2016-05-03 14:15:59
timeless@gmail.com
spelling: succeeded
1 file changed with 1 insertions and 1 deletions:
0 comments (0 inline, 0 general)
kallithea/lib/dbmigrate/migrate/versioning/util/__init__.py
Show inline comments
 
#!/usr/bin/env python2
 
# -*- coding: utf-8 -*-
 
""".. currentmodule:: migrate.versioning.util"""
 

	
 
import warnings
 
import logging
 
from decorator import decorator
 
from pkg_resources import EntryPoint
 

	
 
from sqlalchemy import create_engine
 
from sqlalchemy.engine import Engine
 
from sqlalchemy.pool import StaticPool
 

	
 
from kallithea.lib.dbmigrate.migrate import exceptions
 
from kallithea.lib.dbmigrate.migrate.versioning.util.keyedinstance import KeyedInstance
 
from kallithea.lib.dbmigrate.migrate.versioning.util.importpath import import_path
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 
def load_model(dotted_name):
 
    """Import module and use module-level variable".
 

	
 
    :param dotted_name: path to model in form of string: ``some.python.module:Class``
 

	
 
    .. versionchanged:: 0.5.4
 

	
 
    """
 
    if isinstance(dotted_name, basestring):
 
        if ':' not in dotted_name:
 
            # backwards compatibility
 
            warnings.warn('model should be in form of module.model:User '
 
                'and not module.model.User', exceptions.MigrateDeprecationWarning)
 
            dotted_name = ':'.join(dotted_name.rsplit('.', 1))
 
        return EntryPoint.parse('x=%s' % dotted_name).load(False)
 
    else:
 
        # Assume it's already loaded.
 
        return dotted_name
 

	
 
def asbool(obj):
 
    """Do everything to use object as bool"""
 
    if isinstance(obj, basestring):
 
        obj = obj.strip().lower()
 
        if obj in ['true', 'yes', 'on', 'y', 't', '1']:
 
            return True
 
        elif obj in ['false', 'no', 'off', 'n', 'f', '0']:
 
            return False
 
        else:
 
            raise ValueError("String is not true/false: %r" % obj)
 
    if obj in (True, False):
 
        return bool(obj)
 
    else:
 
        raise ValueError("String is not true/false: %r" % obj)
 

	
 
def guess_obj_type(obj):
 
    """Do everything to guess object type from string
 

	
 
    Tries to convert to `int`, `bool` and finally returns if not succeded.
 
    Tries to convert to `int`, `bool` and finally returns if not succeeded.
 

	
 
    .. versionadded: 0.5.4
 
    """
 

	
 
    result = None
 

	
 
    try:
 
        result = int(obj)
 
    except:
 
        pass
 

	
 
    if result is None:
 
        try:
 
            result = asbool(obj)
 
        except:
 
            pass
 

	
 
    if result is not None:
 
        return result
 
    else:
 
        return obj
 

	
 
@decorator
 
def catch_known_errors(f, *a, **kw):
 
    """Decorator that catches known api errors
 

	
 
    .. versionadded: 0.5.4
 
    """
 

	
 
    try:
 
        return f(*a, **kw)
 
    except exceptions.PathFoundError as e:
 
        raise exceptions.KnownError("The path %s already exists" % e.args[0])
 

	
 
def construct_engine(engine, **opts):
 
    """.. versionadded:: 0.5.4
 

	
 
    Constructs and returns SQLAlchemy engine.
 

	
 
    Currently, there are 2 ways to pass create_engine options to :mod:`migrate.versioning.api` functions:
 

	
 
    :param engine: connection string or a existing engine
 
    :param engine_dict: python dictionary of options to pass to `create_engine`
 
    :param engine_arg_*: keyword parameters to pass to `create_engine` (evaluated with :func:`migrate.versioning.util.guess_obj_type`)
 
    :type engine_dict: dict
 
    :type engine: string or Engine instance
 
    :type engine_arg_*: string
 
    :returns: SQLAlchemy Engine
 

	
 
    .. note::
 

	
 
        keyword parameters override ``engine_dict`` values.
 

	
 
    """
 
    if isinstance(engine, Engine):
 
        return engine
 
    elif not isinstance(engine, basestring):
 
        raise ValueError("you need to pass either an existing engine or a database uri")
 

	
 
    # get options for create_engine
 
    if opts.get('engine_dict') and isinstance(opts['engine_dict'], dict):
 
        kwargs = opts['engine_dict']
 
    else:
 
        kwargs = dict()
 

	
 
    # DEPRECATED: handle echo the old way
 
    echo = asbool(opts.get('echo', False))
 
    if echo:
 
        warnings.warn('echo=True parameter is deprecated, pass '
 
            'engine_arg_echo=True or engine_dict={"echo": True}',
 
            exceptions.MigrateDeprecationWarning)
 
        kwargs['echo'] = echo
 

	
 
    # parse keyword arguments
 
    for key, value in opts.iteritems():
 
        if key.startswith('engine_arg_'):
 
            kwargs[key[11:]] = guess_obj_type(value)
 

	
 
    log.debug('Constructing engine')
 
    # TODO: return create_engine(engine, poolclass=StaticPool, **kwargs)
 
    # seems like 0.5.x branch does not work with engine.dispose and staticpool
 
    return create_engine(engine, **kwargs)
 

	
 
@decorator
 
def with_engine(f, *a, **kw):
 
    """Decorator for :mod:`migrate.versioning.api` functions
 
    to safely close resources after function usage.
 

	
 
    Passes engine parameters to :func:`construct_engine` and
 
    resulting parameter is available as kw['engine'].
 

	
 
    Engine is disposed after wrapped function is executed.
 

	
 
    .. versionadded: 0.6.0
 
    """
 
    url = a[0]
0 comments (0 inline, 0 general)