summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2015-06-18 20:52:19 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2015-06-18 20:52:19 -0400
commit9ac68646a848dd991c505ffed4be3361dd40b612 (patch)
tree3d401857af5812cbc4527a695f152d16e3498679
parent89a6fa3c1436a490d3c664ee5d37aa95e2d8a9a9 (diff)
downloadalembic-9ac68646a848dd991c505ffed4be3361dd40b612.tar.gz
- wip
-rw-r--r--alembic/ddl/base.py151
-rw-r--r--alembic/operations/batch.py2
-rw-r--r--alembic/util/sqla_compat.py61
3 files changed, 71 insertions, 143 deletions
diff --git a/alembic/ddl/base.py b/alembic/ddl/base.py
index dbdc991..f19a9a9 100644
--- a/alembic/ddl/base.py
+++ b/alembic/ddl/base.py
@@ -1,94 +1,20 @@
import functools
from sqlalchemy.ext.compiler import compiles
-from sqlalchemy.schema import DDLElement, Column, \
- ForeignKeyConstraint, CheckConstraint
+from sqlalchemy.schema import Column
from sqlalchemy import Integer
-from sqlalchemy import types as sqltypes
-from sqlalchemy.sql.visitors import traverse
from .. import util
-if util.sqla_09:
- from sqlalchemy.sql.elements import quoted_name
-
-
-class AlterTable(DDLElement):
-
- """Represent an ALTER TABLE statement.
-
- Only the string name and optional schema name of the table
- is required, not a full Table object.
-
- """
-
- def __init__(self, table_name, schema=None):
- self.table_name = table_name
- self.schema = schema
-
-
-class RenameTable(AlterTable):
-
- def __init__(self, old_table_name, new_table_name, schema=None):
- super(RenameTable, self).__init__(old_table_name, schema=schema)
- self.new_table_name = new_table_name
-
-
-class AlterColumn(AlterTable):
-
- def __init__(self, name, column_name, schema=None,
- existing_type=None,
- existing_nullable=None,
- existing_server_default=None):
- super(AlterColumn, self).__init__(name, schema=schema)
- self.column_name = column_name
- self.existing_type = sqltypes.to_instance(existing_type) \
- if existing_type is not None else None
- self.existing_nullable = existing_nullable
- self.existing_server_default = existing_server_default
-
-
-class ColumnNullable(AlterColumn):
-
- def __init__(self, name, column_name, nullable, **kw):
- super(ColumnNullable, self).__init__(name, column_name,
- **kw)
- self.nullable = nullable
-
-
-class ColumnType(AlterColumn):
-
- def __init__(self, name, column_name, type_, **kw):
- super(ColumnType, self).__init__(name, column_name,
- **kw)
- self.type_ = sqltypes.to_instance(type_)
-
-
-class ColumnName(AlterColumn):
-
- def __init__(self, name, column_name, newname, **kw):
- super(ColumnName, self).__init__(name, column_name, **kw)
- self.newname = newname
+# backwards compat
+from ..util.sqla_compat import ( # noqa
+ _table_for_constraint,
+ _columns_for_constraint, _fk_spec, _is_type_bound, _find_columns)
-class ColumnDefault(AlterColumn):
-
- def __init__(self, name, column_name, default, **kw):
- super(ColumnDefault, self).__init__(name, column_name, **kw)
- self.default = default
-
-
-class AddColumn(AlterTable):
-
- def __init__(self, name, column, schema=None):
- super(AddColumn, self).__init__(name, schema=schema)
- self.column = column
-
-
-class DropColumn(AlterTable):
-
- def __init__(self, name, column, schema=None):
- super(DropColumn, self).__init__(name, schema=schema)
- self.column = column
+from ..operations import RenameTable, AddColumn, DropColumn, \
+ ColumnNullable, ColumnDefault, ColumnType, ColumnName
+if util.sqla_09:
+ from sqlalchemy.sql.elements import quoted_name
@compiles(RenameTable)
@@ -154,65 +80,6 @@ def visit_column_default(element, compiler, **kw):
)
-def _table_for_constraint(constraint):
- if isinstance(constraint, ForeignKeyConstraint):
- return constraint.parent
- else:
- return constraint.table
-
-
-def _columns_for_constraint(constraint):
- if isinstance(constraint, ForeignKeyConstraint):
- return [fk.parent for fk in constraint.elements]
- elif isinstance(constraint, CheckConstraint):
- return _find_columns(constraint.sqltext)
- else:
- return list(constraint.columns)
-
-
-def _fk_spec(constraint):
- if util.sqla_100:
- source_columns = [
- constraint.columns[key].name for key in constraint.column_keys]
- else:
- source_columns = [
- element.parent.name for element in constraint.elements]
-
- source_table = constraint.parent.name
- source_schema = constraint.parent.schema
- target_schema = constraint.elements[0].column.table.schema
- target_table = constraint.elements[0].column.table.name
- target_columns = [element.column.name for element in constraint.elements]
-
- return (
- source_schema, source_table,
- source_columns, target_schema, target_table, target_columns)
-
-
-def _is_type_bound(constraint):
- # this deals with SQLAlchemy #3260, don't copy CHECK constraints
- # that will be generated by the type.
- if util.sqla_100:
- # new feature added for #3260
- return constraint._type_bound
- else:
- # old way, look at what we know Boolean/Enum to use
- return (
- constraint._create_rule is not None and
- isinstance(
- getattr(constraint._create_rule, "target", None),
- sqltypes.SchemaType)
- )
-
-
-def _find_columns(clause):
- """locate Column objects within the given expression."""
-
- cols = set()
- traverse(clause, {}, {'column': cols.add})
- return cols
-
-
def quote_dotted(name, quote):
"""quote the elements of a dotted name"""
diff --git a/alembic/operations/batch.py b/alembic/operations/batch.py
index 9644a33..726df78 100644
--- a/alembic/operations/batch.py
+++ b/alembic/operations/batch.py
@@ -4,7 +4,7 @@ from sqlalchemy import types as sqltypes
from sqlalchemy import schema as sql_schema
from sqlalchemy.util import OrderedDict
from .. import util
-from ..ddl.base import _columns_for_constraint, _is_type_bound
+from ..util.sqla_compat import _columns_for_constraint, _is_type_bound
class BatchOperationsImpl(object):
diff --git a/alembic/util/sqla_compat.py b/alembic/util/sqla_compat.py
index 41badd4..d2025aa 100644
--- a/alembic/util/sqla_compat.py
+++ b/alembic/util/sqla_compat.py
@@ -1,5 +1,8 @@
import re
from sqlalchemy import __version__
+from sqlalchemy.schema import ForeignKeyConstraint, CheckConstraint
+from sqlalchemy import types as sqltypes
+from sqlalchemy.sql.visitors import traverse
def _safe_int(value):
@@ -22,3 +25,61 @@ sqla_099 = _vers >= (0, 9, 9)
sqla_100 = _vers >= (1, 0, 0)
sqla_105 = _vers >= (1, 0, 5)
+
+def _table_for_constraint(constraint):
+ if isinstance(constraint, ForeignKeyConstraint):
+ return constraint.parent
+ else:
+ return constraint.table
+
+
+def _columns_for_constraint(constraint):
+ if isinstance(constraint, ForeignKeyConstraint):
+ return [fk.parent for fk in constraint.elements]
+ elif isinstance(constraint, CheckConstraint):
+ return _find_columns(constraint.sqltext)
+ else:
+ return list(constraint.columns)
+
+
+def _fk_spec(constraint):
+ if sqla_100:
+ source_columns = [
+ constraint.columns[key].name for key in constraint.column_keys]
+ else:
+ source_columns = [
+ element.parent.name for element in constraint.elements]
+
+ source_table = constraint.parent.name
+ source_schema = constraint.parent.schema
+ target_schema = constraint.elements[0].column.table.schema
+ target_table = constraint.elements[0].column.table.name
+ target_columns = [element.column.name for element in constraint.elements]
+
+ return (
+ source_schema, source_table,
+ source_columns, target_schema, target_table, target_columns)
+
+
+def _is_type_bound(constraint):
+ # this deals with SQLAlchemy #3260, don't copy CHECK constraints
+ # that will be generated by the type.
+ if sqla_100:
+ # new feature added for #3260
+ return constraint._type_bound
+ else:
+ # old way, look at what we know Boolean/Enum to use
+ return (
+ constraint._create_rule is not None and
+ isinstance(
+ getattr(constraint._create_rule, "target", None),
+ sqltypes.SchemaType)
+ )
+
+
+def _find_columns(clause):
+ """locate Column objects within the given expression."""
+
+ cols = set()
+ traverse(clause, {}, {'column': cols.add})
+ return cols