updated changeset documentation, added alter_metadata to all schema classes
This commit is contained in:
parent
75e93aa410
commit
08e5d10786
@ -1,7 +1,7 @@
|
|||||||
0.5.5
|
0.5.5
|
||||||
-----
|
-----
|
||||||
|
|
||||||
- alter column constructs now accept `alter_metadata` parameter. If True, it will modify Column/Table objects according to changes. Otherwise, everything will be untouched.
|
- 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.
|
||||||
- complete refactoring of :class:`~migrate.changeset.schema.ColumnDelta` (fixes issue 23)
|
- complete refactoring of :class:`~migrate.changeset.schema.ColumnDelta` (fixes issue 23)
|
||||||
- added support for :ref:`firebird <firebird-d>`
|
- added support for :ref:`firebird <firebird-d>`
|
||||||
- fixed bug when column.alter(server_default='string') was not properly set
|
- fixed bug when column.alter(server_default='string') was not properly set
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
Database changeset
|
Database changeset
|
||||||
******************
|
******************
|
||||||
|
|
||||||
.. currentmodule:: migrate.changeset
|
.. currentmodule:: migrate.changeset.schema
|
||||||
|
|
||||||
Importing :mod:`migrate.changeset` adds some new methods to existing
|
Importing :mod:`migrate.changeset` adds some new methods to existing
|
||||||
SA objects, as well as creating functions of its own. Most operations
|
SA objects, as well as creating functions of its own. Most operations
|
||||||
@ -21,6 +21,10 @@ Changeset operations can be used independently of SQLAlchemy Migrate's
|
|||||||
For more information, see the generated documentation for
|
For more information, see the generated documentation for
|
||||||
:mod:`migrate.changeset`.
|
:mod:`migrate.changeset`.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
alter_metadata keyword defaults to True.
|
||||||
|
|
||||||
Column
|
Column
|
||||||
======
|
======
|
||||||
|
|
||||||
@ -33,7 +37,7 @@ Given a standard SQLAlchemy table::
|
|||||||
|
|
||||||
.. _column-create:
|
.. _column-create:
|
||||||
|
|
||||||
Create a column::
|
:meth:`Create a column <ChangesetColumn.create>`::
|
||||||
|
|
||||||
col = Column('col1', String)
|
col = Column('col1', String)
|
||||||
col.create(table)
|
col.create(table)
|
||||||
@ -43,14 +47,14 @@ Create a column::
|
|||||||
|
|
||||||
.. _column-drop:
|
.. _column-drop:
|
||||||
|
|
||||||
Drop a column::
|
:meth:`Drop a column <ChangesetColumn.drop>`::
|
||||||
|
|
||||||
col.drop()
|
col.drop()
|
||||||
|
|
||||||
|
|
||||||
.. _column-alter:
|
.. _column-alter:
|
||||||
|
|
||||||
Alter a column::
|
:meth:`Alter a column <ChangesetColumn.alter>`::
|
||||||
|
|
||||||
col.alter(name='col2')
|
col.alter(name='col2')
|
||||||
|
|
||||||
@ -75,9 +79,9 @@ Alter a column::
|
|||||||
Table
|
Table
|
||||||
=====
|
=====
|
||||||
|
|
||||||
SQLAlchemy supports `table create/drop`_
|
SQLAlchemy supports `table create/drop`_.
|
||||||
|
|
||||||
Rename a table::
|
:meth:`Rename a table <ChangesetTable.rename>`::
|
||||||
|
|
||||||
table.rename('newtablename')
|
table.rename('newtablename')
|
||||||
|
|
||||||
@ -90,9 +94,9 @@ Rename a table::
|
|||||||
Index
|
Index
|
||||||
=====
|
=====
|
||||||
|
|
||||||
SQLAlchemy supports `index create/drop`_
|
SQLAlchemy supports `index create/drop`_.
|
||||||
|
|
||||||
Rename an index, given an SQLAlchemy ``Index`` object::
|
:meth:`Rename an index <migrate.changeset.schema.ChangesetIndex.rename>`, given an SQLAlchemy ``Index`` object::
|
||||||
|
|
||||||
index.rename('newindexname')
|
index.rename('newindexname')
|
||||||
|
|
||||||
|
@ -25,72 +25,72 @@ __all__ = [
|
|||||||
DEFAULT_ALTER_METADATA = True
|
DEFAULT_ALTER_METADATA = True
|
||||||
|
|
||||||
|
|
||||||
def create_column(column, table=None, *p, **k):
|
def create_column(column, table=None, *p, **kw):
|
||||||
"""Create a column, given the table
|
"""Create a column, given the table.
|
||||||
|
|
||||||
API to :meth:`ChangesetColumn.create`
|
API to :meth:`ChangesetColumn.create`.
|
||||||
"""
|
"""
|
||||||
if table is not None:
|
if table is not None:
|
||||||
return table.create_column(column, *p, **k)
|
return table.create_column(column, *p, **kw)
|
||||||
return column.create(*p, **k)
|
return column.create(*p, **kw)
|
||||||
|
|
||||||
|
|
||||||
def drop_column(column, table=None, *p, **k):
|
def drop_column(column, table=None, *p, **kw):
|
||||||
"""Drop a column, given the table
|
"""Drop a column, given the table.
|
||||||
|
|
||||||
API to :meth:`ChangesetColumn.drop`
|
API to :meth:`ChangesetColumn.drop`.
|
||||||
"""
|
"""
|
||||||
if table is not None:
|
if table is not None:
|
||||||
return table.drop_column(column, *p, **k)
|
return table.drop_column(column, *p, **kw)
|
||||||
return column.drop(*p, **k)
|
return column.drop(*p, **kw)
|
||||||
|
|
||||||
|
|
||||||
def rename_table(table, name, engine=None):
|
def rename_table(table, name, engine=None, **kw):
|
||||||
"""Rename a table.
|
"""Rename a table.
|
||||||
|
|
||||||
If Table instance is given, engine is not used.
|
If Table instance is given, engine is not used.
|
||||||
|
|
||||||
API to :meth:`ChangesetTable.rename`
|
API to :meth:`ChangesetTable.rename`.
|
||||||
|
|
||||||
:param table: Table to be renamed
|
:param table: Table to be renamed.
|
||||||
:param name: new name
|
:param name: New name for Table.
|
||||||
:param engine: Engine instance
|
:param engine: Engine instance.
|
||||||
:type table: string or Table instance
|
:type table: string or Table instance
|
||||||
:type name: string
|
:type name: string
|
||||||
:type engine: obj
|
:type engine: obj
|
||||||
"""
|
"""
|
||||||
table = _to_table(table, engine)
|
table = _to_table(table, engine)
|
||||||
table.rename(name)
|
table.rename(name, **kw)
|
||||||
|
|
||||||
|
|
||||||
def rename_index(index, name, table=None, engine=None):
|
def rename_index(index, name, table=None, engine=None, **kw):
|
||||||
"""Rename an index.
|
"""Rename an index.
|
||||||
|
|
||||||
If Index and Table object instances are given,
|
If Index instance is given,
|
||||||
table and engine are not used.
|
table and engine are not used.
|
||||||
|
|
||||||
API to :meth:`ChangesetIndex.rename`
|
API to :meth:`ChangesetIndex.rename`.
|
||||||
|
|
||||||
:param index: Index to be renamed
|
:param index: Index to be renamed.
|
||||||
:param name: new name
|
:param name: New name for index.
|
||||||
:param table: Table to which Index is reffered
|
:param table: Table to which Index is reffered.
|
||||||
:param engine: Engine instance
|
:param engine: Engine instance.
|
||||||
:type index: string or Index instance
|
:type index: string or Index instance
|
||||||
:type name: string
|
:type name: string
|
||||||
:type table: string or Table instance
|
:type table: string or Table instance
|
||||||
:type engine: obj
|
:type engine: obj
|
||||||
"""
|
"""
|
||||||
index = _to_index(index, table, engine)
|
index = _to_index(index, table, engine)
|
||||||
index.rename(name)
|
index.rename(name, **kw)
|
||||||
|
|
||||||
|
|
||||||
def alter_column(*p, **k):
|
def alter_column(*p, **k):
|
||||||
"""Alter a column.
|
"""Alter a column.
|
||||||
|
|
||||||
Direct API to :class:`ColumnDelta`
|
Direct API to :class:`ColumnDelta`.
|
||||||
|
|
||||||
:param table: Table or table name (will issue reflection)
|
:param table: Table or table name (will issue reflection).
|
||||||
:param engine: Will be used for reflection
|
:param engine: Will be used for reflection.
|
||||||
:param alter_metadata: Defaults to True. It will alter changes also to objects.
|
:param alter_metadata: Defaults to True. It will alter changes also to objects.
|
||||||
:returns: :class:`Columndelta` instance
|
:returns: :class:`Columndelta` instance
|
||||||
"""
|
"""
|
||||||
@ -378,19 +378,30 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem):
|
|||||||
class ChangesetTable(object):
|
class ChangesetTable(object):
|
||||||
"""Changeset extensions to SQLAlchemy tables."""
|
"""Changeset extensions to SQLAlchemy tables."""
|
||||||
|
|
||||||
def create_column(self, column, **kw):
|
def create_column(self, column, *p, **kw):
|
||||||
"""Creates a column.
|
"""Creates a column.
|
||||||
|
|
||||||
The column parameter may be a column definition or the name of
|
The column parameter may be a column definition or the name of
|
||||||
a column in this table.
|
a column in this table.
|
||||||
|
|
||||||
|
API to :meth:`ChangesetColumn.create`
|
||||||
|
|
||||||
|
:param column: Column to be created
|
||||||
|
:type column: Column instance or string
|
||||||
"""
|
"""
|
||||||
if not isinstance(column, sqlalchemy.Column):
|
if not isinstance(column, sqlalchemy.Column):
|
||||||
# It's a column name
|
# It's a column name
|
||||||
column = getattr(self.c, str(column))
|
column = getattr(self.c, str(column))
|
||||||
column.create(table=self)
|
column.create(table=self, *p, **kw)
|
||||||
|
|
||||||
def drop_column(self, column, **kw):
|
def drop_column(self, column, *p, **kw):
|
||||||
"""Drop a column, given its name or definition."""
|
"""Drop a column, given its name or definition.
|
||||||
|
|
||||||
|
API to :meth:`ChangesetColumn.drop`
|
||||||
|
|
||||||
|
:param column: Column to be droped
|
||||||
|
:type column: Column instance or string
|
||||||
|
"""
|
||||||
if not isinstance(column, sqlalchemy.Column):
|
if not isinstance(column, sqlalchemy.Column):
|
||||||
# It's a column name
|
# It's a column name
|
||||||
try:
|
try:
|
||||||
@ -400,23 +411,27 @@ class ChangesetTable(object):
|
|||||||
# its entire definition to drop the column, just its
|
# its entire definition to drop the column, just its
|
||||||
# name, so create a dummy column with the same name.
|
# name, so create a dummy column with the same name.
|
||||||
column = sqlalchemy.Column(str(column))
|
column = sqlalchemy.Column(str(column))
|
||||||
column.drop(table=self)
|
column.drop(table=self, *p, **kw)
|
||||||
|
|
||||||
def rename(self, name, *args, **kwargs):
|
def rename(self, name, *args, **kwargs):
|
||||||
"""Rename this table.
|
"""Rename this table.
|
||||||
|
|
||||||
This changes both the database name and the name of this
|
:param name: New name of the table.
|
||||||
Python object
|
:type name: string
|
||||||
|
:param alter_metadata: If True, table will be removed from metadata
|
||||||
|
:type alter_metadata: bool
|
||||||
"""
|
"""
|
||||||
|
self.alter_metadata = kwargs.pop('alter_metadata', DEFAULT_ALTER_METADATA)
|
||||||
engine = self.bind
|
engine = self.bind
|
||||||
self.new_name = name
|
self.new_name = name
|
||||||
visitorcallable = get_engine_visitor(engine, 'schemachanger')
|
visitorcallable = get_engine_visitor(engine, 'schemachanger')
|
||||||
run_single_visitor(engine, visitorcallable, self, *args, **kwargs)
|
run_single_visitor(engine, visitorcallable, self, *args, **kwargs)
|
||||||
|
|
||||||
# Fix metadata registration
|
# Fix metadata registration
|
||||||
self.name = name
|
if self.alter_metadata:
|
||||||
self.deregister()
|
self.name = name
|
||||||
self._set_parent(self.metadata)
|
self.deregister()
|
||||||
|
self._set_parent(self.metadata)
|
||||||
|
|
||||||
def _meta_key(self):
|
def _meta_key(self):
|
||||||
return sqlalchemy.schema._get_table_key(self.name, self.schema)
|
return sqlalchemy.schema._get_table_key(self.name, self.schema)
|
||||||
@ -430,7 +445,7 @@ class ChangesetTable(object):
|
|||||||
|
|
||||||
|
|
||||||
class ChangesetColumn(object):
|
class ChangesetColumn(object):
|
||||||
"""Changeset extensions to SQLAlchemy columns"""
|
"""Changeset extensions to SQLAlchemy columns."""
|
||||||
|
|
||||||
def alter(self, *p, **k):
|
def alter(self, *p, **k):
|
||||||
"""Alter a column's definition: ``ALTER TABLE ALTER COLUMN``.
|
"""Alter a column's definition: ``ALTER TABLE ALTER COLUMN``.
|
||||||
@ -442,7 +457,8 @@ class ChangesetColumn(object):
|
|||||||
|
|
||||||
col.alter(Column('myint', Integer, DefaultClause('foobar')))
|
col.alter(Column('myint', Integer, DefaultClause('foobar')))
|
||||||
col.alter('myint', Integer, server_default='foobar', nullable=False)
|
col.alter('myint', Integer, server_default='foobar', nullable=False)
|
||||||
col.alter(DefaultClause('foobar'), name='myint', type=Integer, nullable=False)
|
col.alter(DefaultClause('foobar'), name='myint', type=Integer,\
|
||||||
|
nullable=False)
|
||||||
|
|
||||||
Column name, type, server_default, and nullable may be changed
|
Column name, type, server_default, and nullable may be changed
|
||||||
here.
|
here.
|
||||||
@ -461,14 +477,29 @@ class ChangesetColumn(object):
|
|||||||
|
|
||||||
Assumes the given table exists. ``ALTER TABLE ADD COLUMN``,
|
Assumes the given table exists. ``ALTER TABLE ADD COLUMN``,
|
||||||
for most databases.
|
for most databases.
|
||||||
|
|
||||||
|
:param table: Table instance to create on.
|
||||||
|
:param index_name: Creates :class:`ChangesetIndex` on this column.
|
||||||
|
:param unique_name: Creates :class:\
|
||||||
|
`~migrate.changeset.constraint.UniqueConstraint` on this column.
|
||||||
|
:param primary_key_name: Creates :class:\
|
||||||
|
`~migrate.changeset.constraint.PrimaryKeyConstraint` on this column.
|
||||||
|
:param alter_metadata: If True, column will be added to table object.
|
||||||
|
:type table: Table instance
|
||||||
|
:type index_name: string
|
||||||
|
:type unique_name: string
|
||||||
|
:type primary_key_name: string
|
||||||
|
:type alter_metadata: bool
|
||||||
"""
|
"""
|
||||||
|
self.alter_metadata = kwargs.pop('alter_metadata', DEFAULT_ALTER_METADATA)
|
||||||
self.index_name = index_name
|
self.index_name = index_name
|
||||||
self.unique_name = unique_name
|
self.unique_name = unique_name
|
||||||
self.primary_key_name = primary_key_name
|
self.primary_key_name = primary_key_name
|
||||||
for cons in ('index_name', 'unique_name', 'primary_key_name'):
|
for cons in ('index_name', 'unique_name', 'primary_key_name'):
|
||||||
self._check_sanity_constraints(cons)
|
self._check_sanity_constraints(cons)
|
||||||
|
|
||||||
self.add_to_table(table)
|
if self.alter_metadata:
|
||||||
|
self.add_to_table(table)
|
||||||
engine = self.table.bind
|
engine = self.table.bind
|
||||||
visitorcallable = get_engine_visitor(engine, 'columngenerator')
|
visitorcallable = get_engine_visitor(engine, 'columngenerator')
|
||||||
engine._run_visitor(visitorcallable, self, *args, **kwargs)
|
engine._run_visitor(visitorcallable, self, *args, **kwargs)
|
||||||
@ -478,13 +509,20 @@ class ChangesetColumn(object):
|
|||||||
"""Drop this column from the database, leaving its table intact.
|
"""Drop this column from the database, leaving its table intact.
|
||||||
|
|
||||||
``ALTER TABLE DROP COLUMN``, for most databases.
|
``ALTER TABLE DROP COLUMN``, for most databases.
|
||||||
|
|
||||||
|
:param alter_metadata: If True, column will be removed from table object.
|
||||||
|
:type alter_metadata: bool
|
||||||
"""
|
"""
|
||||||
|
self.alter_metadata = kwargs.pop('alter_metadata', DEFAULT_ALTER_METADATA)
|
||||||
if table is not None:
|
if table is not None:
|
||||||
self.table = table
|
self.table = table
|
||||||
engine = self.table.bind
|
engine = self.table.bind
|
||||||
self.remove_from_table(self.table, unset_table=False)
|
if self.alter_metadata:
|
||||||
|
self.remove_from_table(self.table, unset_table=False)
|
||||||
visitorcallable = get_engine_visitor(engine, 'columndropper')
|
visitorcallable = get_engine_visitor(engine, 'columndropper')
|
||||||
engine._run_visitor(visitorcallable, self, *args, **kwargs)
|
engine._run_visitor(visitorcallable, self, *args, **kwargs)
|
||||||
|
if self.alter_metadata:
|
||||||
|
self.table = None
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def add_to_table(self, table):
|
def add_to_table(self, table):
|
||||||
@ -515,7 +553,7 @@ class ChangesetColumn(object):
|
|||||||
*[c.copy(**kw) for c in self.constraints])
|
*[c.copy(**kw) for c in self.constraints])
|
||||||
|
|
||||||
def _check_sanity_constraints(self, name):
|
def _check_sanity_constraints(self, name):
|
||||||
|
"""Check if constraints names are correct"""
|
||||||
obj = getattr(self, name)
|
obj = getattr(self, name)
|
||||||
if (getattr(self, name[:-5]) and not obj):
|
if (getattr(self, name[:-5]) and not obj):
|
||||||
raise InvalidConstraintError("Column.create() accepts index_name,"
|
raise InvalidConstraintError("Column.create() accepts index_name,"
|
||||||
@ -533,14 +571,18 @@ class ChangesetIndex(object):
|
|||||||
def rename(self, name, *args, **kwargs):
|
def rename(self, name, *args, **kwargs):
|
||||||
"""Change the name of an index.
|
"""Change the name of an index.
|
||||||
|
|
||||||
This changes both the Python object name and the database
|
:param name: New name of the Index.
|
||||||
name.
|
:type name: string
|
||||||
|
:param alter_metadata: If True, Index object will be altered.
|
||||||
|
:type alter_metadata: bool
|
||||||
"""
|
"""
|
||||||
|
self.alter_metadata = kwargs.pop('alter_metadata', DEFAULT_ALTER_METADATA)
|
||||||
engine = self.table.bind
|
engine = self.table.bind
|
||||||
self.new_name = name
|
self.new_name = name
|
||||||
visitorcallable = get_engine_visitor(engine, 'schemachanger')
|
visitorcallable = get_engine_visitor(engine, 'schemachanger')
|
||||||
engine._run_visitor(visitorcallable, self, *args, **kwargs)
|
engine._run_visitor(visitorcallable, self, *args, **kwargs)
|
||||||
self.name = name
|
if self.alter_metadata:
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
|
||||||
class ChangesetDefaultClause(object):
|
class ChangesetDefaultClause(object):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user