update docs, delete obsolete code in constraints
This commit is contained in:
parent
431d22be61
commit
cc82a1ad12
@ -116,12 +116,14 @@ Module :mod:`repository <migrate.versioning.repository>`
|
||||
.. automodule:: migrate.versioning.repository
|
||||
:members:
|
||||
:synopsis: SQLAlchemy migrate repository management
|
||||
:member-order: groupwise
|
||||
|
||||
Module :mod:`schema <migrate.versioning.schema>`
|
||||
------------------------------------------------
|
||||
|
||||
.. automodule:: migrate.versioning.schema
|
||||
:members:
|
||||
:member-order: groupwise
|
||||
:synopsis: Database schema management
|
||||
|
||||
Module :mod:`schemadiff <migrate.versioning.schemadiff>`
|
||||
@ -136,15 +138,18 @@ Module :mod:`script <migrate.versioning.script>`
|
||||
|
||||
.. automodule:: migrate.versioning.script.base
|
||||
:synopsis: Script utilities
|
||||
:member-order: groupwise
|
||||
:members:
|
||||
|
||||
.. automodule:: migrate.versioning.script.py
|
||||
:members:
|
||||
:member-order: groupwise
|
||||
:inherited-members:
|
||||
:show-inheritance:
|
||||
|
||||
.. automodule:: migrate.versioning.script.sql
|
||||
:members:
|
||||
:member-order: groupwise
|
||||
:show-inheritance:
|
||||
:inherited-members:
|
||||
|
||||
@ -167,4 +172,5 @@ Module :mod:`version <migrate.versioning.version>`
|
||||
|
||||
.. automodule:: migrate.versioning.version
|
||||
:members:
|
||||
:member-order: groupwise
|
||||
:synopsis: Version management
|
||||
|
@ -13,7 +13,7 @@ from migrate.changeset import constraint, exceptions
|
||||
SchemaIterator = sa.engine.SchemaIterator
|
||||
|
||||
|
||||
class RawAlterTableVisitor(object):
|
||||
class AlterTableVisitor(SchemaIterator):
|
||||
"""Common operations for ``ALTER TABLE`` statements."""
|
||||
|
||||
def _to_table(self, param):
|
||||
@ -24,13 +24,6 @@ class RawAlterTableVisitor(object):
|
||||
ret = param
|
||||
return ret
|
||||
|
||||
def _to_table_name(self, param):
|
||||
"""Returns the table name for the given param object."""
|
||||
ret = self._to_table(param)
|
||||
if isinstance(ret, sa.Table):
|
||||
ret = ret.fullname
|
||||
return ret
|
||||
|
||||
def start_alter_table(self, param):
|
||||
"""Returns the start of an ``ALTER TABLE`` SQL-Statement.
|
||||
|
||||
@ -70,11 +63,6 @@ class RawAlterTableVisitor(object):
|
||||
return ret
|
||||
|
||||
|
||||
class AlterTableVisitor(SchemaIterator, RawAlterTableVisitor):
|
||||
"""Common operations for ``ALTER TABLE`` statements"""
|
||||
pass
|
||||
|
||||
|
||||
class ANSIColumnGenerator(AlterTableVisitor, SchemaGenerator):
|
||||
"""Extends ansisql generator for column creation (alter table add col)"""
|
||||
|
||||
@ -82,7 +70,7 @@ class ANSIColumnGenerator(AlterTableVisitor, SchemaGenerator):
|
||||
"""Create a column (table already exists).
|
||||
|
||||
:param column: column object
|
||||
:type column: :class:`sqlalchemy.Column`
|
||||
:type column: :class:`sqlalchemy.Column` instance
|
||||
"""
|
||||
table = self.start_alter_table(column)
|
||||
self.append("ADD ")
|
||||
@ -94,7 +82,7 @@ class ANSIColumnGenerator(AlterTableVisitor, SchemaGenerator):
|
||||
"""Default table visitor, does nothing.
|
||||
|
||||
:param table: table object
|
||||
:type table: :class:`sqlalchemy.Table`
|
||||
:type table: :class:`sqlalchemy.Table` instance
|
||||
"""
|
||||
pass
|
||||
|
||||
@ -124,7 +112,7 @@ class ANSISchemaChanger(AlterTableVisitor, SchemaGenerator):
|
||||
All items may be renamed. Columns can also have many of their properties -
|
||||
type, for example - changed.
|
||||
|
||||
Each function is passed a tuple, containing (object,name); where
|
||||
Each function is passed a tuple, containing (object, name); where
|
||||
object is a type of object you'd expect for that function
|
||||
(ie. table for visit_table) and name is the object's new
|
||||
name. NONE means the name is unchanged.
|
||||
@ -137,6 +125,14 @@ class ANSISchemaChanger(AlterTableVisitor, SchemaGenerator):
|
||||
self.append("RENAME TO %s" % self.preparer.quote(newname, table.quote))
|
||||
self.execute()
|
||||
|
||||
def visit_index(self, param):
|
||||
"""Rename an index"""
|
||||
index, newname = param
|
||||
self.append("ALTER INDEX %s RENAME TO %s" %
|
||||
(self.preparer.quote(self._validate_identifier(index.name, True), index.quote),
|
||||
self.preparer.quote(self._validate_identifier(newname, True) , index.quote)))
|
||||
self.execute()
|
||||
|
||||
def visit_column(self, delta):
|
||||
"""Rename/change a column."""
|
||||
# ALTER COLUMN is implemented as several ALTER statements
|
||||
@ -152,14 +148,12 @@ class ANSISchemaChanger(AlterTableVisitor, SchemaGenerator):
|
||||
if 'name' in keys:
|
||||
self._run_subvisit(delta, self._visit_column_name)
|
||||
|
||||
def _run_subvisit(self, delta, func, col_name=None, table_name=None):
|
||||
if table_name is None:
|
||||
table_name = self._to_table(delta.table)
|
||||
if col_name is None:
|
||||
col_name = delta.current_name
|
||||
ret = func(table_name, col_name, delta)
|
||||
def _run_subvisit(self, delta, func):
|
||||
"""Runs visit method based on what needs to be changed on column"""
|
||||
table = self._to_table(delta.table)
|
||||
col_name = delta.current_name
|
||||
ret = func(table, col_name, delta)
|
||||
self.execute()
|
||||
return ret
|
||||
|
||||
def _visit_column_foreign_key(self, delta):
|
||||
table = delta.table
|
||||
@ -183,10 +177,10 @@ class ANSISchemaChanger(AlterTableVisitor, SchemaGenerator):
|
||||
cons.drop()
|
||||
cons.create()
|
||||
|
||||
def _visit_column_nullable(self, table_name, col_name, delta):
|
||||
def _visit_column_nullable(self, table, col_name, delta):
|
||||
nullable = delta['nullable']
|
||||
table = self._to_table(delta)
|
||||
self.start_alter_table(table_name)
|
||||
table = self._to_table(table)
|
||||
self.start_alter_table(table)
|
||||
# TODO: use preparer.format_column
|
||||
self.append("ALTER COLUMN %s " % self.preparer.quote_identifier(col_name))
|
||||
if nullable:
|
||||
@ -194,50 +188,41 @@ class ANSISchemaChanger(AlterTableVisitor, SchemaGenerator):
|
||||
else:
|
||||
self.append("SET NOT NULL")
|
||||
|
||||
def _visit_column_default(self, table_name, col_name, delta):
|
||||
def _visit_column_default(self, table, col_name, delta):
|
||||
server_default = delta['server_default']
|
||||
# Dummy column: get_col_default_string needs a column for some
|
||||
# reason
|
||||
dummy = sa.Column(None, None, server_default=server_default)
|
||||
default_text = self.get_column_default_string(dummy)
|
||||
self.start_alter_table(table_name)
|
||||
self.start_alter_table(table)
|
||||
# TODO: use preparer.format_column
|
||||
self.append("ALTER COLUMN %s " % self.preparer.quote_identifier(col_name))
|
||||
if default_text is not None:
|
||||
# TODO: format needed?
|
||||
self.append("SET DEFAULT %s" % default_text)
|
||||
else:
|
||||
self.append("DROP DEFAULT")
|
||||
|
||||
def _visit_column_type(self, table_name, col_name, delta):
|
||||
type = delta['type']
|
||||
if not isinstance(type, sa.types.AbstractType):
|
||||
def _visit_column_type(self, table, col_name, delta):
|
||||
type_ = delta['type']
|
||||
if not isinstance(type_, sa.types.AbstractType):
|
||||
# It's the class itself, not an instance... make an
|
||||
# instance
|
||||
type = type()
|
||||
type_text = type.dialect_impl(self.dialect).get_col_spec()
|
||||
self.start_alter_table(table_name)
|
||||
type_ = type_()
|
||||
type_text = type_.dialect_impl(self.dialect).get_col_spec()
|
||||
self.start_alter_table(table)
|
||||
# TODO: does type need formating?
|
||||
# TODO: use preparer.format_column
|
||||
self.append("ALTER COLUMN %s TYPE %s" %
|
||||
(self.preparer.quote_identifier(col_name), type_text))
|
||||
|
||||
def _visit_column_name(self, table_name, col_name, delta):
|
||||
def _visit_column_name(self, table, col_name, delta):
|
||||
new_name = delta['name']
|
||||
self.start_alter_table(table_name)
|
||||
self.start_alter_table(table)
|
||||
# TODO: use preparer.format_column
|
||||
self.append('RENAME COLUMN %s TO %s' % \
|
||||
(self.preparer.quote_identifier(col_name),
|
||||
self.preparer.quote_identifier(new_name)))
|
||||
|
||||
def visit_index(self, param):
|
||||
"""Rename an index; #36"""
|
||||
index, newname = param
|
||||
self.append("ALTER INDEX %s RENAME TO %s" %
|
||||
(self.preparer.quote(self._validate_identifier(index.name, True), index.quote),
|
||||
self.preparer.quote(self._validate_identifier(newname, True) , index.quote)))
|
||||
self.execute()
|
||||
|
||||
|
||||
class ANSIConstraintCommon(AlterTableVisitor):
|
||||
"""
|
||||
@ -250,12 +235,10 @@ class ANSIConstraintCommon(AlterTableVisitor):
|
||||
"""Gets a name for the given constraint.
|
||||
|
||||
If the name is already set it will be used otherwise the
|
||||
constraint's :meth:`autoname
|
||||
<migrate.changeset.constraint.ConstraintChangeset.autoname>`
|
||||
constraint's :meth:`autoname <migrate.changeset.constraint.ConstraintChangeset.autoname>`
|
||||
method is used.
|
||||
|
||||
:param cons: constraint object
|
||||
:type cons: :class:`migrate.changeset.constraint.ConstraintChangeset`
|
||||
"""
|
||||
if cons.name is not None:
|
||||
ret = cons.name
|
||||
@ -331,9 +314,7 @@ class ANSIFKGenerator(AlterTableVisitor, SchemaGenerator):
|
||||
"""Extends ansisql generator for column creation (alter table add col)"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.fk = kwargs.get('fk', None)
|
||||
if self.fk:
|
||||
del kwargs['fk']
|
||||
self.fk = kwargs.pop('fk', None)
|
||||
super(ANSIFKGenerator, self).__init__(*args, **kwargs)
|
||||
|
||||
def visit_column(self, column):
|
||||
|
@ -6,10 +6,9 @@ from sqlalchemy import schema
|
||||
|
||||
|
||||
class ConstraintChangeset(object):
|
||||
"""Base class for Constraint classes.
|
||||
"""
|
||||
"""Base class for Constraint classes."""
|
||||
|
||||
def _normalize_columns(self, cols, fullname=False):
|
||||
def _normalize_columns(self, cols, table_name=False):
|
||||
"""Given: column objects or names; return col names and
|
||||
(maybe) a table"""
|
||||
colnames = []
|
||||
@ -18,62 +17,48 @@ class ConstraintChangeset(object):
|
||||
if isinstance(col, schema.Column):
|
||||
if col.table is not None and table is None:
|
||||
table = col.table
|
||||
if fullname:
|
||||
if table_name:
|
||||
col = '.'.join((col.table.name, col.name))
|
||||
else:
|
||||
col = col.name
|
||||
colnames.append(col)
|
||||
return colnames, table
|
||||
|
||||
def create(self, engine=None):
|
||||
def create(self, *args, **kwargs):
|
||||
"""Create the constraint in the database.
|
||||
|
||||
:param engine: the database engine to use. If this is
|
||||
:keyword:`None` the instance's engine will be used
|
||||
:param engine: the database engine to use. If this is \
|
||||
:keyword:`None` the instance's engine will be used
|
||||
:type engine: :class:`sqlalchemy.engine.base.Engine`
|
||||
"""
|
||||
if engine is None:
|
||||
engine = self.engine
|
||||
engine.create(self)
|
||||
from migrate.changeset.databases.visitor import get_engine_visitor
|
||||
visitorcallable = get_engine_visitor(self.table.bind,
|
||||
'constraintgenerator')
|
||||
_engine_run_visitor(self.table.bind, visitorcallable, self)
|
||||
|
||||
def drop(self, engine=None):
|
||||
def drop(self, *args, **kwargs):
|
||||
"""Drop the constraint from the database.
|
||||
|
||||
:param engine: the database engine to use. If this is
|
||||
:keyword:`None` the instance's engine will be used
|
||||
:type engine: :class:`sqlalchemy.engine.base.Engine`
|
||||
"""
|
||||
if engine is None:
|
||||
engine = self.engine
|
||||
engine.drop(self)
|
||||
|
||||
def _derived_metadata(self):
|
||||
return self.table._derived_metadata()
|
||||
from migrate.changeset.databases.visitor import get_engine_visitor
|
||||
visitorcallable = get_engine_visitor(self.table.bind,
|
||||
'constraintdropper')
|
||||
_engine_run_visitor(self.table.bind, visitorcallable, self)
|
||||
self.columns.clear()
|
||||
return self
|
||||
|
||||
def accept_schema_visitor(self, visitor, *p, **k):
|
||||
"""
|
||||
:raises: :exc:`NotImplementedError` if this method is not \
|
||||
overridden by a subclass
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def _accept_schema_visitor(self, visitor, func, *p, **k):
|
||||
"""Call the visitor only if it defines the given function"""
|
||||
try:
|
||||
func = getattr(visitor, func)
|
||||
except AttributeError:
|
||||
return
|
||||
return func(self)
|
||||
return getattr(visitor, self._func)(self)
|
||||
|
||||
def autoname(self):
|
||||
"""Automatically generate a name for the constraint instance.
|
||||
|
||||
Subclasses must implement this method.
|
||||
|
||||
:raises: :exc:`NotImplementedError` if this method is not \
|
||||
overridden by a subclass
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
def _engine_run_visitor(engine, visitorcallable, element, **kwargs):
|
||||
@ -87,6 +72,8 @@ def _engine_run_visitor(engine, visitorcallable, element, **kwargs):
|
||||
class PrimaryKeyConstraint(ConstraintChangeset, schema.PrimaryKeyConstraint):
|
||||
"""Primary key constraint class."""
|
||||
|
||||
_func = 'visit_migrate_primary_key_constraint'
|
||||
|
||||
def __init__(self, *cols, **kwargs):
|
||||
colnames, table = self._normalize_columns(cols)
|
||||
table = kwargs.pop('table', table)
|
||||
@ -94,86 +81,47 @@ class PrimaryKeyConstraint(ConstraintChangeset, schema.PrimaryKeyConstraint):
|
||||
if table is not None:
|
||||
self._set_parent(table)
|
||||
|
||||
def _set_parent(self, table):
|
||||
self.table = table
|
||||
return super(ConstraintChangeset, self)._set_parent(table)
|
||||
|
||||
def create(self, *args, **kwargs):
|
||||
from migrate.changeset.databases.visitor import get_engine_visitor
|
||||
visitorcallable = get_engine_visitor(self.table.bind,
|
||||
'constraintgenerator')
|
||||
_engine_run_visitor(self.table.bind, visitorcallable, self)
|
||||
|
||||
def autoname(self):
|
||||
"""Mimic the database's automatic constraint names"""
|
||||
ret = "%(table)s_pkey" % dict(table=self.table.name)
|
||||
return ret
|
||||
|
||||
def drop(self, *args, **kwargs):
|
||||
from migrate.changeset.databases.visitor import get_engine_visitor
|
||||
visitorcallable = get_engine_visitor(self.table.bind,
|
||||
'constraintdropper')
|
||||
_engine_run_visitor(self.table.bind, visitorcallable, self)
|
||||
self.columns.clear()
|
||||
return self
|
||||
|
||||
def accept_schema_visitor(self, visitor, *p, **k):
|
||||
func = 'visit_migrate_primary_key_constraint'
|
||||
return self._accept_schema_visitor(visitor, func, *p, **k)
|
||||
return "%s_pkey" % self.table.name
|
||||
|
||||
|
||||
class ForeignKeyConstraint(ConstraintChangeset, schema.ForeignKeyConstraint):
|
||||
"""Foreign key constraint class."""
|
||||
|
||||
_func = 'visit_migrate_foreign_key_constraint'
|
||||
|
||||
def __init__(self, columns, refcolumns, *p, **k):
|
||||
colnames, table = self._normalize_columns(columns)
|
||||
table = k.pop('table', table)
|
||||
refcolnames, reftable = self._normalize_columns(refcolumns,
|
||||
fullname=True)
|
||||
table_name=True)
|
||||
super(ForeignKeyConstraint, self).__init__(colnames, refcolnames, *p,
|
||||
**k)
|
||||
if table is not None:
|
||||
self._set_parent(table)
|
||||
|
||||
def _get_referenced(self):
|
||||
@property
|
||||
def referenced(self):
|
||||
return [e.column for e in self.elements]
|
||||
referenced = property(_get_referenced)
|
||||
|
||||
def _get_reftable(self):
|
||||
@property
|
||||
def reftable(self):
|
||||
return self.referenced[0].table
|
||||
reftable = property(_get_reftable)
|
||||
|
||||
def autoname(self):
|
||||
"""Mimic the database's automatic constraint names"""
|
||||
ret = "%(table)s_%(reftable)s_fkey"%dict(
|
||||
ret = "%(table)s_%(reftable)s_fkey" % dict(
|
||||
table=self.table.name,
|
||||
reftable=self.reftable.name,
|
||||
)
|
||||
reftable=self.reftable.name,)
|
||||
return ret
|
||||
|
||||
def create(self, *args, **kwargs):
|
||||
from migrate.changeset.databases.visitor import get_engine_visitor
|
||||
visitorcallable = get_engine_visitor(self.table.bind,
|
||||
'constraintgenerator')
|
||||
_engine_run_visitor(self.table.bind, visitorcallable, self)
|
||||
return self
|
||||
|
||||
def drop(self, *args, **kwargs):
|
||||
from migrate.changeset.databases.visitor import get_engine_visitor
|
||||
visitorcallable = get_engine_visitor(self.table.bind,
|
||||
'constraintdropper')
|
||||
_engine_run_visitor(self.table.bind, visitorcallable, self)
|
||||
self.columns.clear()
|
||||
return self
|
||||
|
||||
def accept_schema_visitor(self, visitor, *p, **k):
|
||||
func = 'visit_migrate_foreign_key_constraint'
|
||||
return self._accept_schema_visitor(visitor, func, *p, **k)
|
||||
|
||||
|
||||
class CheckConstraint(ConstraintChangeset, schema.CheckConstraint):
|
||||
"""Check constraint class."""
|
||||
|
||||
_func = 'visit_migrate_check_constraint'
|
||||
|
||||
def __init__(self, sqltext, *args, **kwargs):
|
||||
cols = kwargs.pop('columns')
|
||||
colnames, table = self._normalize_columns(cols)
|
||||
@ -184,28 +132,6 @@ class CheckConstraint(ConstraintChangeset, schema.CheckConstraint):
|
||||
self._set_parent(table)
|
||||
self.colnames = colnames
|
||||
|
||||
def _set_parent(self, table):
|
||||
self.table = table
|
||||
return super(ConstraintChangeset, self)._set_parent(table)
|
||||
|
||||
def create(self):
|
||||
from migrate.changeset.databases.visitor import get_engine_visitor
|
||||
visitorcallable = get_engine_visitor(self.table.bind,
|
||||
'constraintgenerator')
|
||||
_engine_run_visitor(self.table.bind, visitorcallable, self)
|
||||
|
||||
def drop(self):
|
||||
from migrate.changeset.databases.visitor import get_engine_visitor
|
||||
visitorcallable = get_engine_visitor(self.table.bind,
|
||||
'constraintdropper')
|
||||
_engine_run_visitor(self.table.bind, visitorcallable, self)
|
||||
self.columns.clear()
|
||||
return self
|
||||
|
||||
def autoname(self):
|
||||
return "%(table)s_%(cols)s_check" % \
|
||||
{"table": self.table.name, "cols": "_".join(self.colnames)}
|
||||
|
||||
def accept_schema_visitor(self, visitor, *args, **kwargs):
|
||||
func = 'visit_migrate_check_constraint'
|
||||
return self._accept_schema_visitor(visitor, func, *args, **kwargs)
|
||||
dict(table=self.table.name, cols="_".join(self.colnames))
|
||||
|
@ -3,8 +3,8 @@
|
||||
implementations.
|
||||
"""
|
||||
__all__=[
|
||||
'postgres',
|
||||
'sqlite',
|
||||
'mysql',
|
||||
'oracle',
|
||||
'postgres',
|
||||
'sqlite',
|
||||
'mysql',
|
||||
'oracle',
|
||||
]
|
||||
|
@ -2,9 +2,10 @@
|
||||
MySQL database specific implementations of changeset classes.
|
||||
"""
|
||||
|
||||
from migrate.changeset import ansisql, exceptions
|
||||
from sqlalchemy.databases import mysql as sa_base
|
||||
#import sqlalchemy as sa
|
||||
|
||||
from migrate.changeset import ansisql, exceptions
|
||||
|
||||
|
||||
MySQLSchemaGenerator = sa_base.MySQLSchemaGenerator
|
||||
|
||||
|
@ -9,8 +9,7 @@ import sqlalchemy as sa
|
||||
OracleSchemaGenerator = sa_base.OracleSchemaGenerator
|
||||
|
||||
|
||||
class OracleColumnGenerator(OracleSchemaGenerator,
|
||||
ansisql.ANSIColumnGenerator):
|
||||
class OracleColumnGenerator(OracleSchemaGenerator, ansisql.ANSIColumnGenerator):
|
||||
pass
|
||||
|
||||
|
||||
@ -40,7 +39,7 @@ class OracleSchemaChanger(OracleSchemaGenerator, ansisql.ANSISchemaChanger):
|
||||
if 'name' in keys:
|
||||
self._run_subvisit(delta, self._visit_column_name)
|
||||
|
||||
def _visit_column_change(self, table_name, col_name, delta):
|
||||
def _visit_column_change(self, table, col_name, delta):
|
||||
if not hasattr(delta, 'result_column'):
|
||||
# Oracle needs the whole column definition, not just a
|
||||
# lone name/type
|
||||
@ -76,8 +75,7 @@ class OracleSchemaChanger(OracleSchemaGenerator, ansisql.ANSISchemaChanger):
|
||||
if dropdefault_hack:
|
||||
column.server_default = None
|
||||
|
||||
# TODO: format from table
|
||||
self.start_alter_table(self.preparer.quote(table_name, True))
|
||||
self.start_alter_table(self.preparer.format_table(table))
|
||||
self.append("MODIFY ")
|
||||
self.append(colspec)
|
||||
|
||||
|
@ -7,6 +7,7 @@ import sqlalchemy
|
||||
|
||||
from migrate.changeset.databases.visitor import get_engine_visitor
|
||||
|
||||
|
||||
__all__ = [
|
||||
'create_column',
|
||||
'drop_column',
|
||||
@ -37,10 +38,18 @@ def drop_column(column, table=None, *p, **k):
|
||||
|
||||
|
||||
def rename_table(table, name, engine=None):
|
||||
"""Rename a table, given the table's current name and the new
|
||||
name.
|
||||
|
||||
"""Rename a table.
|
||||
|
||||
If Table instance is given, engine is not used.
|
||||
|
||||
API to :meth:`table.rename`
|
||||
|
||||
:param table: Table to be renamed
|
||||
:param name: new name
|
||||
:param engine: Engine instance
|
||||
:type table: string or Table instance
|
||||
:type name: string
|
||||
:type engine: obj
|
||||
"""
|
||||
table = _to_table(table, engine)
|
||||
table.rename(name)
|
||||
@ -49,15 +58,24 @@ def rename_table(table, name, engine=None):
|
||||
def rename_index(index, name, table=None, engine=None):
|
||||
"""Rename an index.
|
||||
|
||||
Takes an index name/object, a table name/object, and an
|
||||
engine. Engine and table aren't required if an index object is
|
||||
given.
|
||||
If Index and Table object instances are given,
|
||||
table and engine are not used.
|
||||
|
||||
API to :meth:`index.rename`
|
||||
|
||||
:param index: Index to be renamed
|
||||
:param name: new name
|
||||
:param table: Table to which Index is reffered
|
||||
:param engine: Engine instance
|
||||
:type index: string or Index instance
|
||||
:type name: string
|
||||
:type table: string or Table instance
|
||||
:type engine: obj
|
||||
"""
|
||||
index = _to_index(index, table, engine)
|
||||
index.rename(name)
|
||||
|
||||
|
||||
def alter_column(*p, **k):
|
||||
"""Alter a column.
|
||||
|
||||
@ -70,10 +88,12 @@ def alter_column(*p, **k):
|
||||
col = p[0]
|
||||
else:
|
||||
col = None
|
||||
|
||||
if 'table' not in k:
|
||||
k['table'] = col.table
|
||||
if 'engine' not in k:
|
||||
k['engine'] = k['table'].bind
|
||||
|
||||
engine = k['engine']
|
||||
delta = _ColumnDelta(*p, **k)
|
||||
visitorcallable = get_engine_visitor(engine, 'schemachanger')
|
||||
@ -102,8 +122,10 @@ def alter_column(*p, **k):
|
||||
|
||||
|
||||
def _to_table(table, engine=None):
|
||||
"""Return if instance of Table, else construct new with metadata"""
|
||||
if isinstance(table, sqlalchemy.Table):
|
||||
return table
|
||||
|
||||
# Given: table name, maybe an engine
|
||||
meta = sqlalchemy.MetaData()
|
||||
if engine is not None:
|
||||
@ -112,8 +134,10 @@ def _to_table(table, engine=None):
|
||||
|
||||
|
||||
def _to_index(index, table=None, engine=None):
|
||||
"""Return if instance of Index, else construct new with metadata"""
|
||||
if isinstance(index, sqlalchemy.Index):
|
||||
return index
|
||||
|
||||
# Given: index name; table name required
|
||||
table = _to_table(table, engine)
|
||||
ret = sqlalchemy.Index(index)
|
||||
@ -149,13 +173,10 @@ class _WrapRename(object):
|
||||
self.name = name
|
||||
|
||||
def accept_schema_visitor(self, visitor):
|
||||
if isinstance(self.item, sqlalchemy.Table):
|
||||
suffix = 'table'
|
||||
elif isinstance(self.item, sqlalchemy.Column):
|
||||
suffix = 'column'
|
||||
elif isinstance(self.item, sqlalchemy.Index):
|
||||
suffix = 'index'
|
||||
"""Map Class (Table, Index, Column) to visitor function"""
|
||||
suffix = self.item.__class__.__name__.lower()
|
||||
funcname = 'visit_%s' % suffix
|
||||
|
||||
func = getattr(visitor, funcname)
|
||||
param = self.item, self.name
|
||||
return func(param)
|
||||
@ -207,14 +228,6 @@ class _ColumnDelta(dict):
|
||||
'primary_key',
|
||||
'foreign_key')
|
||||
|
||||
@property
|
||||
def table_name(self):
|
||||
if isinstance(self._table, basestring):
|
||||
ret = self._table
|
||||
else:
|
||||
ret = self._table.name
|
||||
return ret
|
||||
|
||||
@property
|
||||
def table(self):
|
||||
if isinstance(self._table, sqlalchemy.Table):
|
||||
@ -310,16 +323,6 @@ class ChangesetTable(object):
|
||||
column = sqlalchemy.Column(str(column))
|
||||
column.drop(table=self)
|
||||
|
||||
def _meta_key(self):
|
||||
return sqlalchemy.schema._get_table_key(self.name, self.schema)
|
||||
|
||||
def deregister(self):
|
||||
"""Remove this table from its metadata"""
|
||||
key = self._meta_key()
|
||||
meta = self.metadata
|
||||
if key in meta.tables:
|
||||
del meta.tables[key]
|
||||
|
||||
def rename(self, name, *args, **kwargs):
|
||||
"""Rename this table.
|
||||
|
||||
@ -337,16 +340,15 @@ class ChangesetTable(object):
|
||||
self.name = name
|
||||
self._set_parent(meta)
|
||||
|
||||
def _get_fullname(self):
|
||||
"""Fullname should always be up to date"""
|
||||
# Copied from Table constructor
|
||||
if self.schema is not None:
|
||||
ret = "%s.%s" % (self.schema, self.name)
|
||||
else:
|
||||
ret = self.name
|
||||
return ret
|
||||
def _meta_key(self):
|
||||
return sqlalchemy.schema._get_table_key(self.name, self.schema)
|
||||
|
||||
fullname = property(_get_fullname, (lambda self, val: None))
|
||||
def deregister(self):
|
||||
"""Remove this table from its metadata"""
|
||||
key = self._meta_key()
|
||||
meta = self.metadata
|
||||
if key in meta.tables:
|
||||
del meta.tables[key]
|
||||
|
||||
|
||||
class ChangesetColumn(object):
|
||||
@ -384,7 +386,7 @@ class ChangesetColumn(object):
|
||||
visitorcallable = get_engine_visitor(engine, 'columngenerator')
|
||||
engine._run_visitor(visitorcallable, self, *args, **kwargs)
|
||||
|
||||
#add in foreign keys
|
||||
# add in foreign keys
|
||||
if self.foreign_keys:
|
||||
for fk in self.foreign_keys:
|
||||
visitorcallable = get_engine_visitor(engine,
|
||||
|
@ -8,6 +8,7 @@ from migrate.changeset import *
|
||||
|
||||
from test import fixture
|
||||
|
||||
|
||||
class TestConstraint(fixture.DB):
|
||||
level = fixture.DB.CONNECT
|
||||
|
||||
@ -37,7 +38,7 @@ class TestConstraint(fixture.DB):
|
||||
def _define_pk(self, *cols):
|
||||
# Add a pk by creating a PK constraint
|
||||
pk = PrimaryKeyConstraint(table=self.table, *cols)
|
||||
self.assertEquals(list(pk.columns),list(cols))
|
||||
self.assertEquals(list(pk.columns), list(cols))
|
||||
if self.url.startswith('oracle'):
|
||||
# Can't drop Oracle PKs without an explicit name
|
||||
pk.name = 'fgsfds'
|
||||
@ -54,7 +55,7 @@ class TestConstraint(fixture.DB):
|
||||
pk.drop()
|
||||
self.refresh_table()
|
||||
#self.assertEquals(list(self.table.primary_key),list())
|
||||
self.assertEquals(len(self.table.primary_key),0)
|
||||
self.assertEquals(len(self.table.primary_key), 0)
|
||||
self.assert_(isinstance(self.table.primary_key,
|
||||
schema.PrimaryKeyConstraint),self.table.primary_key.__class__)
|
||||
return pk
|
||||
@ -75,7 +76,7 @@ class TestConstraint(fixture.DB):
|
||||
|
||||
if self.url.startswith('mysql'):
|
||||
# MySQL FKs need an index
|
||||
index = Index('index_name',self.table.c.fkey)
|
||||
index = Index('index_name', self.table.c.fkey)
|
||||
index.create()
|
||||
if self.url.startswith('oracle'):
|
||||
# Oracle constraints need a name
|
||||
|
Loading…
x
Reference in New Issue
Block a user