This commit is contained in:
iElectric 2011-04-29 19:27:52 +02:00
commit 86bb3e7e36
11 changed files with 99 additions and 115 deletions

View File

@ -1 +1,2 @@
cb01bf174b05b1590258d6c996b89f60ebd88e5a v0.6 cb01bf174b05b1590258d6c996b89f60ebd88e5a v0.6
c2526dce0768f11e6bf88afb641a6a9058fa685c v0.6.1

View File

@ -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)
--------------------------- ---------------------------

View File

@ -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.

View File

@ -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()

View File

@ -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"""

View File

@ -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):

View File

@ -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'))

View File

@ -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 (

View File

@ -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):

View File

@ -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",

View File

@ -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