merge
This commit is contained in:
commit
86bb3e7e36
1
.hgtags
1
.hgtags
@ -1 +1,2 @@
|
|||||||
cb01bf174b05b1590258d6c996b89f60ebd88e5a v0.6
|
cb01bf174b05b1590258d6c996b89f60ebd88e5a v0.6
|
||||||
|
c2526dce0768f11e6bf88afb641a6a9058fa685c v0.6.1
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
0.6.1 (xxxxxxx)
|
0.6.2 (XXXX-XX-XX)
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
0.6.1 (2011-02-11)
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
Features
|
Features
|
||||||
@ -7,26 +10,31 @@ Features
|
|||||||
- implemented columns adding with unique constraints for sqlite
|
- implemented columns adding with unique constraints for sqlite
|
||||||
- implemented adding unique and foreign key constraints to columns
|
- implemented adding unique and foreign key constraints to columns
|
||||||
for sqlite
|
for sqlite
|
||||||
|
- remove experimental `alter_metadata` parameter
|
||||||
|
|
||||||
Fixed bugs
|
Fixed bugs
|
||||||
******************
|
******************
|
||||||
|
|
||||||
- updated tests for Python 2.7
|
- updated tests for Python 2.7
|
||||||
|
- repository keyword in :func:`api.version_control` can also be unicode
|
||||||
- added if main condition for manage.py script
|
- added if main condition for manage.py script
|
||||||
|
- make :func:`migrate.changeset.constraint.ForeignKeyConstraint.autoname`
|
||||||
|
work with SQLAlchemy 0.5 and 0.6
|
||||||
- fixed case sensitivity in setup.py dependencies
|
- fixed case sensitivity in setup.py dependencies
|
||||||
- moved :mod:`migrate.changeset.exceptions` and :mod:`migrate.versioning.exceptions`
|
- moved :mod:`migrate.changeset.exceptions` and :mod:`migrate.versioning.exceptions`
|
||||||
to :mod:`migrate.exceptions`
|
to :mod:`migrate.exceptions`
|
||||||
- cleared up test output and improved testing of deprecation warnings.
|
- cleared up test output and improved testing of deprecation warnings.
|
||||||
- some documentation fixes
|
- some documentation fixes
|
||||||
- fixed bug with column dropping in sqlite (issue 96)
|
- #107: fixed syntax error in genmodel.py
|
||||||
|
- #96: fixed bug with column dropping in sqlite
|
||||||
|
- #94: fixed bug that prevented non-unique indexes being created
|
||||||
- fixed bug with column dropping involving foreign keys
|
- fixed bug with column dropping involving foreign keys
|
||||||
- fixed bug that prevented non-unique indexes being created (issue 94)
|
|
||||||
- fixed bug when dropping columns with unique constraints in sqlite
|
- fixed bug when dropping columns with unique constraints in sqlite
|
||||||
- rewrite of the schema diff internals, now supporting column
|
- rewrite of the schema diff internals, now supporting column
|
||||||
differences in additon to missing columns and tables.
|
differences in additon to missing columns and tables.
|
||||||
- fixed bug when passing empty list in
|
- fixed bug when passing empty list in
|
||||||
:func:`migrate.versioning.shell.main` failed
|
:func:`migrate.versioning.shell.main` failed
|
||||||
|
- #108: Fixed issues with firebird support.
|
||||||
|
|
||||||
0.6 (11.07.2010)
|
0.6 (11.07.2010)
|
||||||
---------------------------
|
---------------------------
|
||||||
|
@ -47,16 +47,16 @@ master_doc = 'index'
|
|||||||
|
|
||||||
# General information about the project.
|
# General information about the project.
|
||||||
project = u'SQLAlchemy Migrate'
|
project = u'SQLAlchemy Migrate'
|
||||||
copyright = u'2010, Evan Rosson, Jan Dittberner, Domen Kožar'
|
copyright = u'2011, Evan Rosson, Jan Dittberner, Domen Kožar, Chris Withers'
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
# The version info for the project you're documenting, acts as replacement for
|
||||||
# |version| and |release|, also used in various other places throughout the
|
# |version| and |release|, also used in various other places throughout the
|
||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = '0.6'
|
version = '0.6.2'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = '0.6'
|
release = '0.6.2'
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Firebird database specific implementations of changeset classes.
|
Firebird database specific implementations of changeset classes.
|
||||||
"""
|
"""
|
||||||
from sqlalchemy.databases import firebird as sa_base
|
from sqlalchemy.databases import firebird as sa_base
|
||||||
|
from sqlalchemy.schema import PrimaryKeyConstraint
|
||||||
from migrate import exceptions
|
from migrate import exceptions
|
||||||
from migrate.changeset import ansisql, SQLA_06
|
from migrate.changeset import ansisql, SQLA_06
|
||||||
|
|
||||||
@ -27,13 +27,32 @@ class FBColumnDropper(ansisql.ANSIColumnDropper):
|
|||||||
if column.table.primary_key.columns.contains_column(column):
|
if column.table.primary_key.columns.contains_column(column):
|
||||||
column.table.primary_key.drop()
|
column.table.primary_key.drop()
|
||||||
# TODO: recreate primary key if it references more than this column
|
# TODO: recreate primary key if it references more than this column
|
||||||
if column.unique or getattr(column, 'unique_name', None):
|
|
||||||
for cons in column.table.constraints:
|
|
||||||
if cons.contains_column(column):
|
|
||||||
cons.drop()
|
|
||||||
# TODO: recreate unique constraint if it refenrences more than this column
|
|
||||||
|
|
||||||
table = self.start_alter_table(column)
|
for index in column.table.indexes:
|
||||||
|
# "column in index.columns" causes problems as all
|
||||||
|
# column objects compare equal and return a SQL expression
|
||||||
|
if column.name in [col.name for col in index.columns]:
|
||||||
|
index.drop()
|
||||||
|
# TODO: recreate index if it references more than this column
|
||||||
|
|
||||||
|
for cons in column.table.constraints:
|
||||||
|
if isinstance(cons,PrimaryKeyConstraint):
|
||||||
|
# will be deleted only when the column its on
|
||||||
|
# is deleted!
|
||||||
|
continue
|
||||||
|
|
||||||
|
if SQLA_06:
|
||||||
|
should_drop = column.name in cons.columns
|
||||||
|
else:
|
||||||
|
should_drop = cons.contains_column(column) and cons.name
|
||||||
|
if should_drop:
|
||||||
|
self.start_alter_table(column)
|
||||||
|
self.append("DROP CONSTRAINT ")
|
||||||
|
self.append(self.preparer.format_constraint(cons))
|
||||||
|
self.execute()
|
||||||
|
# TODO: recreate unique constraint if it refenrences more than this column
|
||||||
|
|
||||||
|
self.start_alter_table(column)
|
||||||
self.append('DROP %s' % self.preparer.format_column(column))
|
self.append('DROP %s' % self.preparer.format_column(column))
|
||||||
self.execute()
|
self.execute()
|
||||||
|
|
||||||
|
@ -80,10 +80,17 @@ class SQLiteColumnDropper(SQLiteHelper, ansisql.ANSIColumnDropper):
|
|||||||
"""SQLite ColumnDropper"""
|
"""SQLite ColumnDropper"""
|
||||||
|
|
||||||
def _modify_table(self, table, column, delta):
|
def _modify_table(self, table, column, delta):
|
||||||
|
|
||||||
columns = ' ,'.join(map(self.preparer.format_column, table.columns))
|
columns = ' ,'.join(map(self.preparer.format_column, table.columns))
|
||||||
return 'INSERT INTO %(table_name)s SELECT ' + columns + \
|
return 'INSERT INTO %(table_name)s SELECT ' + columns + \
|
||||||
' from migration_tmp'
|
' from migration_tmp'
|
||||||
|
|
||||||
|
def visit_column(self,column):
|
||||||
|
# For SQLite, we *have* to remove the column here so the table
|
||||||
|
# is re-created properly.
|
||||||
|
column.remove_from_table(column.table,unset_table=False)
|
||||||
|
super(SQLiteColumnDropper,self).visit_column(column)
|
||||||
|
|
||||||
|
|
||||||
class SQLiteSchemaChanger(SQLiteHelper, ansisql.ANSISchemaChanger):
|
class SQLiteSchemaChanger(SQLiteHelper, ansisql.ANSISchemaChanger):
|
||||||
"""SQLite SchemaChanger"""
|
"""SQLite SchemaChanger"""
|
||||||
|
@ -29,9 +29,6 @@ __all__ = [
|
|||||||
'ColumnDelta',
|
'ColumnDelta',
|
||||||
]
|
]
|
||||||
|
|
||||||
DEFAULT_ALTER_METADATA = True
|
|
||||||
|
|
||||||
|
|
||||||
def create_column(column, table=None, *p, **kw):
|
def create_column(column, table=None, *p, **kw):
|
||||||
"""Create a column, given the table.
|
"""Create a column, given the table.
|
||||||
|
|
||||||
@ -109,19 +106,11 @@ def alter_column(*p, **k):
|
|||||||
The :class:`~sqlalchemy.engine.base.Engine` to use for table
|
The :class:`~sqlalchemy.engine.base.Engine` to use for table
|
||||||
reflection and schema alterations.
|
reflection and schema alterations.
|
||||||
|
|
||||||
:param alter_metadata:
|
|
||||||
If `True`, which is the default, the
|
|
||||||
:class:`~sqlalchemy.schema.Column` will also modified.
|
|
||||||
If `False`, the :class:`~sqlalchemy.schema.Column` will be left
|
|
||||||
as it was.
|
|
||||||
|
|
||||||
:returns: A :class:`ColumnDelta` instance representing the change.
|
:returns: A :class:`ColumnDelta` instance representing the change.
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
k.setdefault('alter_metadata', DEFAULT_ALTER_METADATA)
|
|
||||||
|
|
||||||
if 'table' not in k and isinstance(p[0], sqlalchemy.Column):
|
if 'table' not in k and isinstance(p[0], sqlalchemy.Column):
|
||||||
k['table'] = p[0].table
|
k['table'] = p[0].table
|
||||||
if 'engine' not in k:
|
if 'engine' not in k:
|
||||||
@ -135,6 +124,12 @@ def alter_column(*p, **k):
|
|||||||
MigrateDeprecationWarning
|
MigrateDeprecationWarning
|
||||||
)
|
)
|
||||||
engine = k['engine']
|
engine = k['engine']
|
||||||
|
|
||||||
|
# enough tests seem to break when metadata is always altered
|
||||||
|
# that this crutch has to be left in until they can be sorted
|
||||||
|
# out
|
||||||
|
k['alter_metadata']=True
|
||||||
|
|
||||||
delta = ColumnDelta(*p, **k)
|
delta = ColumnDelta(*p, **k)
|
||||||
|
|
||||||
visitorcallable = get_engine_visitor(engine, 'schemachanger')
|
visitorcallable = get_engine_visitor(engine, 'schemachanger')
|
||||||
@ -188,11 +183,10 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem):
|
|||||||
:param table: Table at which current Column should be bound to.\
|
:param table: Table at which current Column should be bound to.\
|
||||||
If table name is given, reflection will be used.
|
If table name is given, reflection will be used.
|
||||||
:type table: string or Table instance
|
:type table: string or Table instance
|
||||||
:param alter_metadata: If True, it will apply changes to metadata.
|
|
||||||
:type alter_metadata: bool
|
:param metadata: A :class:`MetaData` instance to store
|
||||||
:param metadata: If `alter_metadata` is true, \
|
reflected table names
|
||||||
metadata is used to reflect table names into
|
|
||||||
:type metadata: :class:`MetaData` instance
|
|
||||||
:param engine: When reflecting tables, either engine or metadata must \
|
:param engine: When reflecting tables, either engine or metadata must \
|
||||||
be specified to acquire engine object.
|
be specified to acquire engine object.
|
||||||
:type engine: :class:`Engine` instance
|
:type engine: :class:`Engine` instance
|
||||||
@ -213,7 +207,11 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem):
|
|||||||
__visit_name__ = 'column'
|
__visit_name__ = 'column'
|
||||||
|
|
||||||
def __init__(self, *p, **kw):
|
def __init__(self, *p, **kw):
|
||||||
|
# 'alter_metadata' is not a public api. It exists purely
|
||||||
|
# as a crutch until the tests that fail when 'alter_metadata'
|
||||||
|
# behaviour always happens can be sorted out
|
||||||
self.alter_metadata = kw.pop("alter_metadata", False)
|
self.alter_metadata = kw.pop("alter_metadata", False)
|
||||||
|
|
||||||
self.meta = kw.pop("metadata", None)
|
self.meta = kw.pop("metadata", None)
|
||||||
self.engine = kw.pop("engine", None)
|
self.engine = kw.pop("engine", None)
|
||||||
|
|
||||||
@ -237,9 +235,11 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem):
|
|||||||
self.apply_diffs(diffs)
|
self.apply_diffs(diffs)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<ColumnDelta altermetadata=%r, %s>' % (self.alter_metadata,
|
return '<ColumnDelta altermetadata=%r, %s>' % (
|
||||||
super(ColumnDelta, self).__repr__())
|
self.alter_metadata,
|
||||||
|
super(ColumnDelta, self).__repr__()
|
||||||
|
)
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
if key not in self.keys():
|
if key not in self.keys():
|
||||||
raise KeyError("No such diff key, available: %s" % self.diffs )
|
raise KeyError("No such diff key, available: %s" % self.diffs )
|
||||||
@ -395,7 +395,6 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem):
|
|||||||
self._table = table
|
self._table = table
|
||||||
if not self.alter_metadata:
|
if not self.alter_metadata:
|
||||||
self._table.meta = sqlalchemy.MetaData(bind=self._table.bind)
|
self._table.meta = sqlalchemy.MetaData(bind=self._table.bind)
|
||||||
|
|
||||||
def _get_result_column(self):
|
def _get_result_column(self):
|
||||||
return getattr(self, '_result_column', None)
|
return getattr(self, '_result_column', None)
|
||||||
|
|
||||||
@ -456,22 +455,18 @@ class ChangesetTable(object):
|
|||||||
|
|
||||||
:param name: New name of the table.
|
:param name: New name of the table.
|
||||||
:type name: string
|
:type name: string
|
||||||
:param alter_metadata: If True, table will be removed from metadata
|
|
||||||
:type alter_metadata: bool
|
|
||||||
:param connection: reuse connection istead of creating new one.
|
:param connection: reuse connection istead of creating new one.
|
||||||
:type connection: :class:`sqlalchemy.engine.base.Connection` instance
|
:type connection: :class:`sqlalchemy.engine.base.Connection` instance
|
||||||
"""
|
"""
|
||||||
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, connection, **kwargs)
|
run_single_visitor(engine, visitorcallable, self, connection, **kwargs)
|
||||||
|
|
||||||
# Fix metadata registration
|
# Fix metadata registration
|
||||||
if self.alter_metadata:
|
self.name = name
|
||||||
self.name = name
|
self.deregister()
|
||||||
self.deregister()
|
self._set_parent(self.metadata)
|
||||||
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)
|
||||||
@ -510,7 +505,6 @@ class ChangesetColumn(object):
|
|||||||
`~migrate.changeset.constraint.UniqueConstraint` on this column.
|
`~migrate.changeset.constraint.UniqueConstraint` on this column.
|
||||||
:param primary_key_name: Creates :class:\
|
:param primary_key_name: Creates :class:\
|
||||||
`~migrate.changeset.constraint.PrimaryKeyConstraint` on this column.
|
`~migrate.changeset.constraint.PrimaryKeyConstraint` on this column.
|
||||||
:param alter_metadata: If True, column will be added to table object.
|
|
||||||
:param populate_default: If True, created column will be \
|
:param populate_default: If True, created column will be \
|
||||||
populated with defaults
|
populated with defaults
|
||||||
:param connection: reuse connection istead of creating new one.
|
:param connection: reuse connection istead of creating new one.
|
||||||
@ -518,22 +512,19 @@ populated with defaults
|
|||||||
:type index_name: string
|
:type index_name: string
|
||||||
:type unique_name: string
|
:type unique_name: string
|
||||||
:type primary_key_name: string
|
:type primary_key_name: string
|
||||||
:type alter_metadata: bool
|
|
||||||
:type populate_default: bool
|
:type populate_default: bool
|
||||||
:type connection: :class:`sqlalchemy.engine.base.Connection` instance
|
:type connection: :class:`sqlalchemy.engine.base.Connection` instance
|
||||||
|
|
||||||
:returns: self
|
:returns: self
|
||||||
"""
|
"""
|
||||||
self.populate_default = populate_default
|
self.populate_default = populate_default
|
||||||
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)
|
||||||
|
|
||||||
if self.alter_metadata:
|
self.add_to_table(table)
|
||||||
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, connection, **kwargs)
|
engine._run_visitor(visitorcallable, self, connection, **kwargs)
|
||||||
@ -550,21 +541,16 @@ populated with defaults
|
|||||||
|
|
||||||
``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
|
|
||||||
:param connection: reuse connection istead of creating new one.
|
:param connection: reuse connection istead of creating new one.
|
||||||
:type connection: :class:`sqlalchemy.engine.base.Connection` instance
|
:type connection: :class:`sqlalchemy.engine.base.Connection` instance
|
||||||
"""
|
"""
|
||||||
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
|
||||||
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, connection, **kwargs)
|
engine._run_visitor(visitorcallable, self, connection, **kwargs)
|
||||||
if self.alter_metadata:
|
self.remove_from_table(self.table, unset_table=False)
|
||||||
self.table = None
|
self.table = None
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def add_to_table(self, table):
|
def add_to_table(self, table):
|
||||||
@ -643,18 +629,14 @@ class ChangesetIndex(object):
|
|||||||
|
|
||||||
:param name: New name of the Index.
|
:param name: New name of the Index.
|
||||||
:type name: string
|
:type name: string
|
||||||
:param alter_metadata: If True, Index object will be altered.
|
|
||||||
:type alter_metadata: bool
|
|
||||||
:param connection: reuse connection istead of creating new one.
|
:param connection: reuse connection istead of creating new one.
|
||||||
:type connection: :class:`sqlalchemy.engine.base.Connection` instance
|
:type connection: :class:`sqlalchemy.engine.base.Connection` instance
|
||||||
"""
|
"""
|
||||||
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, connection, **kwargs)
|
engine._run_visitor(visitorcallable, self, connection, **kwargs)
|
||||||
if self.alter_metadata:
|
self.name = name
|
||||||
self.name = name
|
|
||||||
|
|
||||||
|
|
||||||
class ChangesetDefaultClause(object):
|
class ChangesetDefaultClause(object):
|
||||||
|
@ -262,7 +262,6 @@ class TestAddDropColumn(fixture.DB):
|
|||||||
|
|
||||||
self._check_index(False)
|
self._check_index(False)
|
||||||
|
|
||||||
Index('ix_data', col).drop(bind=self.engine)
|
|
||||||
col.drop()
|
col.drop()
|
||||||
|
|
||||||
@fixture.usedb()
|
@fixture.usedb()
|
||||||
@ -284,7 +283,6 @@ class TestAddDropColumn(fixture.DB):
|
|||||||
|
|
||||||
self._check_index(True)
|
self._check_index(True)
|
||||||
|
|
||||||
Index('ix_data', col).drop(bind=self.engine)
|
|
||||||
col.drop()
|
col.drop()
|
||||||
|
|
||||||
@fixture.usedb()
|
@fixture.usedb()
|
||||||
@ -424,7 +422,8 @@ class TestAddDropColumn(fixture.DB):
|
|||||||
Column('r1', Integer),
|
Column('r1', Integer),
|
||||||
Column('r2', Integer),
|
Column('r2', Integer),
|
||||||
ForeignKeyConstraint(['r1','r2'],
|
ForeignKeyConstraint(['r1','r2'],
|
||||||
[reftable.c.id,reftable.c.jd])
|
[reftable.c.id,reftable.c.jd],
|
||||||
|
name='test_fk')
|
||||||
)
|
)
|
||||||
self.table.create()
|
self.table.create()
|
||||||
|
|
||||||
@ -705,20 +704,6 @@ class TestColumnChange(fixture.DB):
|
|||||||
finally:
|
finally:
|
||||||
cw.__exit__()
|
cw.__exit__()
|
||||||
|
|
||||||
@fixture.usedb()
|
|
||||||
def test_alter_metadata(self):
|
|
||||||
"""Test if alter_metadata is respected"""
|
|
||||||
|
|
||||||
self.table.c.data.alter(type=String(100))
|
|
||||||
|
|
||||||
self.assert_(isinstance(self.table.c.data.type, String))
|
|
||||||
self.assertEqual(self.table.c.data.type.length, 100)
|
|
||||||
|
|
||||||
# nothing should change
|
|
||||||
self.table.c.data.alter(type=String(200),alter_metadata=False)
|
|
||||||
self.assert_(isinstance(self.table.c.data.type, String))
|
|
||||||
self.assertEqual(self.table.c.data.type.length, 100)
|
|
||||||
|
|
||||||
@fixture.usedb()
|
@fixture.usedb()
|
||||||
def test_alter_returns_delta(self):
|
def test_alter_returns_delta(self):
|
||||||
"""Test if alter constructs return delta"""
|
"""Test if alter constructs return delta"""
|
||||||
@ -742,8 +727,7 @@ class TestColumnChange(fixture.DB):
|
|||||||
kw = dict(nullable=False,
|
kw = dict(nullable=False,
|
||||||
server_default='foobar',
|
server_default='foobar',
|
||||||
name='data_new',
|
name='data_new',
|
||||||
type=String(50),
|
type=String(50))
|
||||||
alter_metadata=True)
|
|
||||||
if self.engine.name == 'firebird':
|
if self.engine.name == 'firebird':
|
||||||
del kw['nullable']
|
del kw['nullable']
|
||||||
self.table.c.data.alter(**kw)
|
self.table.c.data.alter(**kw)
|
||||||
@ -840,23 +824,17 @@ class TestColumnDelta(fixture.DB):
|
|||||||
self.verify([], self.mkcol(server_default='foobar'), self.mkcol('id', String, DefaultClause('foobar')))
|
self.verify([], self.mkcol(server_default='foobar'), self.mkcol('id', String, DefaultClause('foobar')))
|
||||||
self.verify(['type'], self.mkcol(server_default='foobar'), self.mkcol('id', Text, DefaultClause('foobar')))
|
self.verify(['type'], self.mkcol(server_default='foobar'), self.mkcol('id', Text, DefaultClause('foobar')))
|
||||||
|
|
||||||
# test alter_metadata
|
|
||||||
col = self.mkcol(server_default='foobar')
|
col = self.mkcol(server_default='foobar')
|
||||||
self.verify(['type'], col, self.mkcol('id', Text, DefaultClause('foobar')), alter_metadata=True)
|
self.verify(['type'], col, self.mkcol('id', Text, DefaultClause('foobar')), alter_metadata=True)
|
||||||
self.assert_(isinstance(col.type, Text))
|
self.assert_(isinstance(col.type, Text))
|
||||||
|
|
||||||
col = self.mkcol()
|
col = self.mkcol()
|
||||||
self.verify(['name', 'server_default', 'type'], col, self.mkcol('beep', Text, DefaultClause('foobar')), alter_metadata=True)
|
self.verify(['name', 'server_default', 'type'], col, self.mkcol('beep', Text, DefaultClause('foobar')),
|
||||||
|
alter_metadata=True)
|
||||||
self.assert_(isinstance(col.type, Text))
|
self.assert_(isinstance(col.type, Text))
|
||||||
self.assertEqual(col.name, 'beep')
|
self.assertEqual(col.name, 'beep')
|
||||||
self.assertEqual(col.server_default.arg, 'foobar')
|
self.assertEqual(col.server_default.arg, 'foobar')
|
||||||
|
|
||||||
col = self.mkcol()
|
|
||||||
self.verify(['name', 'server_default', 'type'], col, self.mkcol('beep', Text, DefaultClause('foobar')), alter_metadata=False)
|
|
||||||
self.assertFalse(isinstance(col.type, Text))
|
|
||||||
self.assertNotEqual(col.name, 'beep')
|
|
||||||
self.assertFalse(col.server_default)
|
|
||||||
|
|
||||||
@fixture.usedb()
|
@fixture.usedb()
|
||||||
def test_deltas_zero_columns(self):
|
def test_deltas_zero_columns(self):
|
||||||
"""Testing ColumnDelta with zero columns"""
|
"""Testing ColumnDelta with zero columns"""
|
||||||
@ -867,24 +845,18 @@ class TestColumnDelta(fixture.DB):
|
|||||||
self.verify(['type'], 'ids', table=self.table.name, type=String(80), engine=self.engine)
|
self.verify(['type'], 'ids', table=self.table.name, type=String(80), engine=self.engine)
|
||||||
self.verify(['type'], 'ids', table=self.table.name, type=String(80), metadata=self.meta)
|
self.verify(['type'], 'ids', table=self.table.name, type=String(80), metadata=self.meta)
|
||||||
|
|
||||||
# check if alter_metadata is respected
|
|
||||||
self.meta.clear()
|
self.meta.clear()
|
||||||
delta = self.verify(['type'], 'ids', table=self.table.name, type=String(80), alter_metadata=True, metadata=self.meta)
|
delta = self.verify(['type'], 'ids', table=self.table.name, type=String(80), metadata=self.meta,
|
||||||
|
alter_metadata=True)
|
||||||
self.assert_(self.table.name in self.meta)
|
self.assert_(self.table.name in self.meta)
|
||||||
self.assertEqual(delta.result_column.type.length, 80)
|
self.assertEqual(delta.result_column.type.length, 80)
|
||||||
self.assertEqual(self.meta.tables.get(self.table.name).c.ids.type.length, 80)
|
self.assertEqual(self.meta.tables.get(self.table.name).c.ids.type.length, 80)
|
||||||
|
|
||||||
self.meta.clear()
|
|
||||||
self.verify(['type'], 'ids', table=self.table.name, type=String(80), alter_metadata=False, engine=self.engine)
|
|
||||||
self.assert_(self.table.name not in self.meta)
|
|
||||||
|
|
||||||
self.meta.clear()
|
|
||||||
self.verify(['type'], 'ids', table=self.table.name, type=String(80), alter_metadata=False, metadata=self.meta)
|
|
||||||
self.assert_(self.table.name not in self.meta)
|
|
||||||
|
|
||||||
# test defaults
|
# test defaults
|
||||||
self.meta.clear()
|
self.meta.clear()
|
||||||
self.verify(['server_default'], 'ids', table=self.table.name, server_default='foobar', alter_metadata=True, metadata=self.meta)
|
self.verify(['server_default'], 'ids', table=self.table.name, server_default='foobar',
|
||||||
|
metadata=self.meta,
|
||||||
|
alter_metadata=True)
|
||||||
self.meta.tables.get(self.table.name).c.ids.server_default.arg == 'foobar'
|
self.meta.tables.get(self.table.name).c.ids.server_default.arg == 'foobar'
|
||||||
|
|
||||||
# test missing parameters
|
# test missing parameters
|
||||||
@ -908,17 +880,11 @@ class TestColumnDelta(fixture.DB):
|
|||||||
self.assertEquals(delta.get('name'), 'blah')
|
self.assertEquals(delta.get('name'), 'blah')
|
||||||
self.assertEquals(delta.current_name, 'id')
|
self.assertEquals(delta.current_name, 'id')
|
||||||
|
|
||||||
# check if alter_metadata is respected
|
|
||||||
col_orig = self.mkcol(primary_key=True)
|
col_orig = self.mkcol(primary_key=True)
|
||||||
self.verify(['name', 'type'], col_orig, name='id12', type=Text, alter_metadata=True)
|
self.verify(['name', 'type'], col_orig, name='id12', type=Text, alter_metadata=True)
|
||||||
self.assert_(isinstance(col_orig.type, Text))
|
self.assert_(isinstance(col_orig.type, Text))
|
||||||
self.assertEqual(col_orig.name, 'id12')
|
self.assertEqual(col_orig.name, 'id12')
|
||||||
|
|
||||||
col_orig = self.mkcol(primary_key=True)
|
|
||||||
self.verify(['name', 'type'], col_orig, name='id12', type=Text, alter_metadata=False)
|
|
||||||
self.assert_(isinstance(col_orig.type, String))
|
|
||||||
self.assertEqual(col_orig.name, 'id')
|
|
||||||
|
|
||||||
# test server default
|
# test server default
|
||||||
col_orig = self.mkcol(primary_key=True)
|
col_orig = self.mkcol(primary_key=True)
|
||||||
delta = self.verify(['server_default'], col_orig, DefaultClause('foobar'))
|
delta = self.verify(['server_default'], col_orig, DefaultClause('foobar'))
|
||||||
|
@ -170,11 +170,11 @@ class ModelGenerator(object):
|
|||||||
modelTable, col.name))
|
modelTable, col.name))
|
||||||
for modelCol, databaseCol, modelDecl, databaseDecl in diffDecl:
|
for modelCol, databaseCol, modelDecl, databaseDecl in diffDecl:
|
||||||
upgradeCommands.append(
|
upgradeCommands.append(
|
||||||
'assert False, "Can\'t alter columns: %s:%s=>%s"',
|
'assert False, "Can\'t alter columns: %s:%s=>%s"' % (
|
||||||
modelTable, modelCol.name, databaseCol.name)
|
modelTable, modelCol.name, databaseCol.name))
|
||||||
downgradeCommands.append(
|
downgradeCommands.append(
|
||||||
'assert False, "Can\'t alter columns: %s:%s=>%s"',
|
'assert False, "Can\'t alter columns: %s:%s=>%s"' % (
|
||||||
modelTable, modelCol.name, databaseCol.name)
|
modelTable, modelCol.name, databaseCol.name))
|
||||||
pre_command = ' meta.bind = migrate_engine'
|
pre_command = ' meta.bind = migrate_engine'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
import shutil
|
import shutil
|
||||||
import warnings
|
import warnings
|
||||||
import logging
|
import logging
|
||||||
|
import inspect
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
|
|
||||||
import migrate
|
import migrate
|
||||||
@ -136,12 +137,12 @@ class PythonScript(base.BaseScript):
|
|||||||
funcname = base.operations[op]
|
funcname = base.operations[op]
|
||||||
script_func = self._func(funcname)
|
script_func = self._func(funcname)
|
||||||
|
|
||||||
try:
|
# check for old way of using engine
|
||||||
script_func(engine)
|
if not inspect.getargspec(script_func)[0]:
|
||||||
except TypeError:
|
raise TypeError("upgrade/downgrade functions must accept engine"
|
||||||
warnings.warn("upgrade/downgrade functions must accept engine"
|
" parameter (since version 0.5.4)")
|
||||||
" parameter (since version > 0.5.4)", MigrateDeprecationWarning)
|
|
||||||
raise
|
script_func(engine)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def module(self):
|
def module(self):
|
||||||
|
2
setup.py
2
setup.py
@ -15,7 +15,7 @@ readme_file = open(os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name = "sqlalchemy-migrate",
|
name = "sqlalchemy-migrate",
|
||||||
version = "0.6.1",
|
version = "0.6.2",
|
||||||
packages = find_packages(exclude=["migrate.tests*"]),
|
packages = find_packages(exclude=["migrate.tests*"]),
|
||||||
include_package_data = True,
|
include_package_data = True,
|
||||||
description = "Database schema migration for SQLAlchemy",
|
description = "Database schema migration for SQLAlchemy",
|
||||||
|
@ -9,6 +9,6 @@ pytz
|
|||||||
http://initd.org/psycopg/tarballs/psycopg2-2.2.2.tar.gz
|
http://initd.org/psycopg/tarballs/psycopg2-2.2.2.tar.gz
|
||||||
pysqlite
|
pysqlite
|
||||||
mysql-python
|
mysql-python
|
||||||
http://downloads.sourceforge.net/firebird/kinterbasdb-3.3.0.tar.bz2
|
http://jenkins.gnuviech-server.de/userContent/kinterbasdb-3.3.0.tar.bz2
|
||||||
virtualenv
|
virtualenv
|
||||||
unittest2
|
unittest2
|
||||||
|
Loading…
x
Reference in New Issue
Block a user