summaryrefslogtreecommitdiff
path: root/migrate/versioning/script
diff options
context:
space:
mode:
Diffstat (limited to 'migrate/versioning/script')
-rw-r--r--migrate/versioning/script/__init__.py6
-rw-r--r--migrate/versioning/script/base.py57
-rw-r--r--migrate/versioning/script/py.py163
-rw-r--r--migrate/versioning/script/sql.py70
4 files changed, 0 insertions, 296 deletions
diff --git a/migrate/versioning/script/__init__.py b/migrate/versioning/script/__init__.py
deleted file mode 100644
index c788eda..0000000
--- a/migrate/versioning/script/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-from migrate.versioning.script.base import BaseScript
-from migrate.versioning.script.py import PythonScript
-from migrate.versioning.script.sql import SqlScript
diff --git a/migrate/versioning/script/base.py b/migrate/versioning/script/base.py
deleted file mode 100644
index 22ca7b4..0000000
--- a/migrate/versioning/script/base.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-import logging
-
-from migrate import exceptions
-from migrate.versioning.config import operations
-from migrate.versioning import pathed
-
-
-log = logging.getLogger(__name__)
-
-class BaseScript(pathed.Pathed):
- """Base class for other types of scripts.
- All scripts have the following properties:
-
- source (script.source())
- The source code of the script
- version (script.version())
- The version number of the script
- operations (script.operations())
- The operations defined by the script: upgrade(), downgrade() or both.
- Returns a tuple of operations.
- Can also check for an operation with ex. script.operation(Script.ops.up)
- """ # TODO: sphinxfy this and implement it correctly
-
- def __init__(self, path):
- log.debug('Loading script %s...' % path)
- self.verify(path)
- super(BaseScript, self).__init__(path)
- log.debug('Script %s loaded successfully' % path)
-
- @classmethod
- def verify(cls, path):
- """Ensure this is a valid script
- This version simply ensures the script file's existence
-
- :raises: :exc:`InvalidScriptError <migrate.exceptions.InvalidScriptError>`
- """
- try:
- cls.require_found(path)
- except:
- raise exceptions.InvalidScriptError(path)
-
- def source(self):
- """:returns: source code of the script.
- :rtype: string
- """
- fd = open(self.path)
- ret = fd.read()
- fd.close()
- return ret
-
- def run(self, engine):
- """Core of each BaseScript subclass.
- This method executes the script.
- """
- raise NotImplementedError()
diff --git a/migrate/versioning/script/py.py b/migrate/versioning/script/py.py
deleted file mode 100644
index 92a8f6b..0000000
--- a/migrate/versioning/script/py.py
+++ /dev/null
@@ -1,163 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import shutil
-import warnings
-import logging
-import inspect
-
-import migrate
-from migrate.versioning import genmodel, schemadiff
-from migrate.versioning.config import operations
-from migrate.versioning.template import Template
-from migrate.versioning.script import base
-from migrate.versioning.util import import_path, load_model, with_engine
-from migrate.exceptions import MigrateDeprecationWarning, InvalidScriptError, ScriptError
-import six
-from six.moves import StringIO
-
-log = logging.getLogger(__name__)
-__all__ = ['PythonScript']
-
-
-class PythonScript(base.BaseScript):
- """Base for Python scripts"""
-
- @classmethod
- def create(cls, path, **opts):
- """Create an empty migration script at specified path
-
- :returns: :class:`PythonScript instance <migrate.versioning.script.py.PythonScript>`"""
- cls.require_notfound(path)
-
- src = Template(opts.pop('templates_path', None)).get_script(theme=opts.pop('templates_theme', None))
- shutil.copy(src, path)
-
- return cls(path)
-
- @classmethod
- def make_update_script_for_model(cls, engine, oldmodel,
- model, repository, **opts):
- """Create a migration script based on difference between two SA models.
-
- :param repository: path to migrate repository
- :param oldmodel: dotted.module.name:SAClass or SAClass object
- :param model: dotted.module.name:SAClass or SAClass object
- :param engine: SQLAlchemy engine
- :type repository: string or :class:`Repository instance <migrate.versioning.repository.Repository>`
- :type oldmodel: string or Class
- :type model: string or Class
- :type engine: Engine instance
- :returns: Upgrade / Downgrade script
- :rtype: string
- """
-
- if isinstance(repository, six.string_types):
- # oh dear, an import cycle!
- from migrate.versioning.repository import Repository
- repository = Repository(repository)
-
- oldmodel = load_model(oldmodel)
- model = load_model(model)
-
- # Compute differences.
- diff = schemadiff.getDiffOfModelAgainstModel(
- model,
- oldmodel,
- excludeTables=[repository.version_table])
- # TODO: diff can be False (there is no difference?)
- decls, upgradeCommands, downgradeCommands = \
- genmodel.ModelGenerator(diff,engine).genB2AMigration()
-
- # Store differences into file.
- src = Template(opts.pop('templates_path', None)).get_script(opts.pop('templates_theme', None))
- f = open(src)
- contents = f.read()
- f.close()
-
- # generate source
- search = 'def upgrade(migrate_engine):'
- contents = contents.replace(search, '\n\n'.join((decls, search)), 1)
- if upgradeCommands:
- contents = contents.replace(' pass', upgradeCommands, 1)
- if downgradeCommands:
- contents = contents.replace(' pass', downgradeCommands, 1)
- return contents
-
- @classmethod
- def verify_module(cls, path):
- """Ensure path is a valid script
-
- :param path: Script location
- :type path: string
- :raises: :exc:`InvalidScriptError <migrate.exceptions.InvalidScriptError>`
- :returns: Python module
- """
- # Try to import and get the upgrade() func
- module = import_path(path)
- try:
- assert callable(module.upgrade)
- except Exception as e:
- raise InvalidScriptError(path + ': %s' % str(e))
- return module
-
- def preview_sql(self, url, step, **args):
- """Mocks SQLAlchemy Engine to store all executed calls in a string
- and runs :meth:`PythonScript.run <migrate.versioning.script.py.PythonScript.run>`
-
- :returns: SQL file
- """
- buf = StringIO()
- args['engine_arg_strategy'] = 'mock'
- args['engine_arg_executor'] = lambda s, p = '': buf.write(str(s) + p)
-
- @with_engine
- def go(url, step, **kw):
- engine = kw.pop('engine')
- self.run(engine, step)
- return buf.getvalue()
-
- return go(url, step, **args)
-
- def run(self, engine, step):
- """Core method of Script file.
- Exectues :func:`update` or :func:`downgrade` functions
-
- :param engine: SQLAlchemy Engine
- :param step: Operation to run
- :type engine: string
- :type step: int
- """
- if step in ('downgrade', 'upgrade'):
- op = step
- elif step > 0:
- op = 'upgrade'
- elif step < 0:
- op = 'downgrade'
- else:
- raise ScriptError("%d is not a valid step" % step)
-
- funcname = base.operations[op]
- script_func = self._func(funcname)
-
- # check for old way of using engine
- if not inspect.getargspec(script_func)[0]:
- raise TypeError("upgrade/downgrade functions must accept engine"
- " parameter (since version 0.5.4)")
-
- script_func(engine)
-
- @property
- def module(self):
- """Calls :meth:`migrate.versioning.script.py.verify_module`
- and returns it.
- """
- if not hasattr(self, '_module'):
- self._module = self.verify_module(self.path)
- return self._module
-
- def _func(self, funcname):
- if not hasattr(self.module, funcname):
- msg = "Function '%s' is not defined in this script"
- raise ScriptError(msg % funcname)
- return getattr(self.module, funcname)
diff --git a/migrate/versioning/script/sql.py b/migrate/versioning/script/sql.py
deleted file mode 100644
index 862bc9f..0000000
--- a/migrate/versioning/script/sql.py
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-import logging
-import re
-import shutil
-
-import sqlparse
-
-from migrate.versioning.script import base
-from migrate.versioning.template import Template
-
-
-log = logging.getLogger(__name__)
-
-class SqlScript(base.BaseScript):
- """A file containing plain SQL statements."""
-
- @classmethod
- def create(cls, path, **opts):
- """Create an empty migration script at specified path
-
- :returns: :class:`SqlScript instance <migrate.versioning.script.sql.SqlScript>`"""
- cls.require_notfound(path)
-
- src = Template(opts.pop('templates_path', None)).get_sql_script(theme=opts.pop('templates_theme', None))
- shutil.copy(src, path)
- return cls(path)
-
- # TODO: why is step parameter even here?
- def run(self, engine, step=None):
- """Runs SQL script through raw dbapi execute call"""
- text = self.source()
- # Don't rely on SA's autocommit here
- # (SA uses .startswith to check if a commit is needed. What if script
- # starts with a comment?)
- conn = engine.connect()
- try:
- trans = conn.begin()
- try:
- # ignore transaction management statements that are
- # redundant in SQL script context and result in
- # operational error being returned.
- #
- # Note: we don't ignore ROLLBACK in migration scripts
- # since its usage would be insane anyway, and we're
- # better to fail on its occurance instead of ignoring it
- # (and committing transaction, which is contradictory to
- # the whole idea of ROLLBACK)
- ignored_statements = ('BEGIN', 'END', 'COMMIT')
- ignored_regex = re.compile('^\s*(%s).*;?$' % '|'.join(ignored_statements),
- re.IGNORECASE)
-
- # NOTE(ihrachys): script may contain multiple statements, and
- # not all drivers reliably handle multistatement queries or
- # commands passed to .execute(), so split them and execute one
- # by one
- text = sqlparse.format(text, strip_comments=True, strip_whitespace=True)
- for statement in sqlparse.split(text):
- if statement:
- if re.match(ignored_regex, statement):
- log.warning('"%s" found in SQL script; ignoring' % statement)
- else:
- conn.execute(statement)
- trans.commit()
- except Exception as e:
- log.error("SQL script %s failed: %s", self.path, e)
- trans.rollback()
- raise
- finally:
- conn.close()