adding connection keyword to ORM methods
This commit is contained in:
parent
b0157137e2
commit
a3d3470d5e
11
TODO
11
TODO
|
@ -10,11 +10,7 @@ make_update_script_for_model:
|
||||||
|
|
||||||
0.6.0
|
0.6.0
|
||||||
|
|
||||||
- make logging stderr and stdout aware
|
|
||||||
- update documentation
|
|
||||||
- update repository migration script
|
- update repository migration script
|
||||||
- readd transaction support
|
|
||||||
- wrap migration into transaction
|
|
||||||
- interactive migration script resolution
|
- interactive migration script resolution
|
||||||
|
|
||||||
- port to unittest2
|
- port to unittest2
|
||||||
|
@ -26,6 +22,7 @@ make_update_script_for_model:
|
||||||
- verbose output on migration failures
|
- verbose output on migration failures
|
||||||
|
|
||||||
|
|
||||||
Documentation
|
Transaction support in 0.6.1
|
||||||
|
- script.run should call engine.transaction()
|
||||||
- better document 'populate_default'
|
- API should support engine and connection as well
|
||||||
|
- tests for transactions
|
||||||
|
|
|
@ -30,6 +30,7 @@ Features
|
||||||
Bug fixes
|
Bug fixes
|
||||||
*****************
|
*****************
|
||||||
|
|
||||||
|
- ORM methods now accept `connection` parameter commonly used for transactions
|
||||||
- `server_defaults` passed to :meth:`Column.create <migrate.changeset.schema.ChangesetColumn.create>`
|
- `server_defaults` passed to :meth:`Column.create <migrate.changeset.schema.ChangesetColumn.create>`
|
||||||
are now issued correctly
|
are now issued correctly
|
||||||
- use SQLAlchemy quoting system to avoid name conflicts (for issue 32)
|
- use SQLAlchemy quoting system to avoid name conflicts (for issue 32)
|
||||||
|
|
|
@ -38,6 +38,8 @@ class ConstraintChangeset(object):
|
||||||
:param engine: the database engine to use. If this is \
|
:param engine: the database engine to use. If this is \
|
||||||
:keyword:`None` the instance's engine will be used
|
:keyword:`None` the instance's engine will be used
|
||||||
:type engine: :class:`sqlalchemy.engine.base.Engine`
|
:type engine: :class:`sqlalchemy.engine.base.Engine`
|
||||||
|
:param connection: reuse connection istead of creating new one.
|
||||||
|
:type connection: :class:`sqlalchemy.engine.base.Connection` instance
|
||||||
"""
|
"""
|
||||||
# TODO: set the parent here instead of in __init__
|
# TODO: set the parent here instead of in __init__
|
||||||
self.__do_imports('constraintgenerator', *a, **kw)
|
self.__do_imports('constraintgenerator', *a, **kw)
|
||||||
|
@ -50,6 +52,8 @@ class ConstraintChangeset(object):
|
||||||
:param cascade: Issue CASCADE drop if database supports it
|
:param cascade: Issue CASCADE drop if database supports it
|
||||||
:type engine: :class:`sqlalchemy.engine.base.Engine`
|
:type engine: :class:`sqlalchemy.engine.base.Engine`
|
||||||
:type cascade: bool
|
:type cascade: bool
|
||||||
|
:param connection: reuse connection istead of creating new one.
|
||||||
|
:type connection: :class:`sqlalchemy.engine.base.Connection` instance
|
||||||
:returns: Instance with cleared columns
|
:returns: Instance with cleared columns
|
||||||
"""
|
"""
|
||||||
self.cascade = kw.pop('cascade', False)
|
self.cascade = kw.pop('cascade', False)
|
||||||
|
@ -63,7 +67,7 @@ class ConstraintChangeset(object):
|
||||||
|
|
||||||
class PrimaryKeyConstraint(ConstraintChangeset, schema.PrimaryKeyConstraint):
|
class PrimaryKeyConstraint(ConstraintChangeset, schema.PrimaryKeyConstraint):
|
||||||
"""Construct PrimaryKeyConstraint
|
"""Construct PrimaryKeyConstraint
|
||||||
|
|
||||||
Migrate's additional parameters:
|
Migrate's additional parameters:
|
||||||
|
|
||||||
:param cols: Columns in constraint.
|
:param cols: Columns in constraint.
|
||||||
|
@ -89,7 +93,7 @@ class PrimaryKeyConstraint(ConstraintChangeset, schema.PrimaryKeyConstraint):
|
||||||
|
|
||||||
class ForeignKeyConstraint(ConstraintChangeset, schema.ForeignKeyConstraint):
|
class ForeignKeyConstraint(ConstraintChangeset, schema.ForeignKeyConstraint):
|
||||||
"""Construct ForeignKeyConstraint
|
"""Construct ForeignKeyConstraint
|
||||||
|
|
||||||
Migrate's additional parameters:
|
Migrate's additional parameters:
|
||||||
|
|
||||||
:param columns: Columns in constraint
|
:param columns: Columns in constraint
|
||||||
|
@ -132,7 +136,7 @@ class CheckConstraint(ConstraintChangeset, schema.CheckConstraint):
|
||||||
"""Construct CheckConstraint
|
"""Construct CheckConstraint
|
||||||
|
|
||||||
Migrate's additional parameters:
|
Migrate's additional parameters:
|
||||||
|
|
||||||
:param sqltext: Plain SQL text to check condition
|
:param sqltext: Plain SQL text to check condition
|
||||||
:param columns: If not name is applied, you must supply this kw\
|
:param columns: If not name is applied, you must supply this kw\
|
||||||
to autoname constraint
|
to autoname constraint
|
||||||
|
@ -165,7 +169,7 @@ class CheckConstraint(ConstraintChangeset, schema.CheckConstraint):
|
||||||
|
|
||||||
class UniqueConstraint(ConstraintChangeset, schema.UniqueConstraint):
|
class UniqueConstraint(ConstraintChangeset, schema.UniqueConstraint):
|
||||||
"""Construct UniqueConstraint
|
"""Construct UniqueConstraint
|
||||||
|
|
||||||
Migrate's additional parameters:
|
Migrate's additional parameters:
|
||||||
|
|
||||||
:param cols: Columns in constraint.
|
:param cols: Columns in constraint.
|
||||||
|
|
|
@ -57,15 +57,22 @@ def get_dialect_visitor(sa_dialect, name):
|
||||||
|
|
||||||
return visitor
|
return visitor
|
||||||
|
|
||||||
def run_single_visitor(engine, visitorcallable, element, **kwargs):
|
def run_single_visitor(engine, visitorcallable, element,
|
||||||
"""Runs only one method on the visitor"""
|
connection=None, **kwargs):
|
||||||
conn = engine.contextual_connect(close_with_result=False)
|
"""Taken from :meth:`sqlalchemy.engine.base.Engine._run_single_visitor`
|
||||||
|
with support for migrate visitors.
|
||||||
|
"""
|
||||||
|
if connection is None:
|
||||||
|
conn = engine.contextual_connect(close_with_result=False)
|
||||||
|
else:
|
||||||
|
conn = connection
|
||||||
|
visitor = visitorcallable(engine.dialect, conn)
|
||||||
try:
|
try:
|
||||||
visitor = visitorcallable(engine.dialect, conn)
|
|
||||||
if hasattr(element, '__migrate_visit_name__'):
|
if hasattr(element, '__migrate_visit_name__'):
|
||||||
fn = getattr(visitor, 'visit_' + element.__migrate_visit_name__)
|
fn = getattr(visitor, 'visit_' + element.__migrate_visit_name__)
|
||||||
else:
|
else:
|
||||||
fn = getattr(visitor, 'visit_' + element.__visit_name__)
|
fn = getattr(visitor, 'visit_' + element.__visit_name__)
|
||||||
fn(element, **kwargs)
|
fn(element, **kwargs)
|
||||||
finally:
|
finally:
|
||||||
conn.close()
|
if connection is None:
|
||||||
|
conn.close()
|
||||||
|
|
|
@ -426,19 +426,21 @@ class ChangesetTable(object):
|
||||||
column = sqlalchemy.Column(str(column), sqlalchemy.Integer())
|
column = sqlalchemy.Column(str(column), sqlalchemy.Integer())
|
||||||
column.drop(table=self, *p, **kw)
|
column.drop(table=self, *p, **kw)
|
||||||
|
|
||||||
def rename(self, name, *args, **kwargs):
|
def rename(self, name, connection=None, **kwargs):
|
||||||
"""Rename this table.
|
"""Rename this table.
|
||||||
|
|
||||||
: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
|
:param alter_metadata: If True, table will be removed from metadata
|
||||||
:type alter_metadata: bool
|
:type alter_metadata: bool
|
||||||
|
:param connection: reuse connection istead of creating new one.
|
||||||
|
:type connection: :class:`sqlalchemy.engine.base.Connection` instance
|
||||||
"""
|
"""
|
||||||
self.alter_metadata = kwargs.pop('alter_metadata', DEFAULT_ALTER_METADATA)
|
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, connection, **kwargs)
|
||||||
|
|
||||||
# Fix metadata registration
|
# Fix metadata registration
|
||||||
if self.alter_metadata:
|
if self.alter_metadata:
|
||||||
|
@ -485,7 +487,7 @@ class ChangesetColumn(object):
|
||||||
return alter_column(self, *p, **k)
|
return alter_column(self, *p, **k)
|
||||||
|
|
||||||
def create(self, table=None, index_name=None, unique_name=None,
|
def create(self, table=None, index_name=None, unique_name=None,
|
||||||
primary_key_name=None, *args, **kwargs):
|
primary_key_name=None, connection=None, **kwargs):
|
||||||
"""Create this column in the database.
|
"""Create this column in the database.
|
||||||
|
|
||||||
Assumes the given table exists. ``ALTER TABLE ADD COLUMN``,
|
Assumes the given table exists. ``ALTER TABLE ADD COLUMN``,
|
||||||
|
@ -500,12 +502,16 @@ class ChangesetColumn(object):
|
||||||
:param alter_metadata: If True, column will be added to table object.
|
: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.
|
||||||
:type table: Table instance
|
:type table: Table instance
|
||||||
: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 alter_metadata: bool
|
||||||
:type populate_default: bool
|
:type populate_default: bool
|
||||||
|
:type connection: :class:`sqlalchemy.engine.base.Connection` instance
|
||||||
|
|
||||||
|
:returns: self
|
||||||
"""
|
"""
|
||||||
self.populate_default = kwargs.pop('populate_default', False)
|
self.populate_default = kwargs.pop('populate_default', False)
|
||||||
self.alter_metadata = kwargs.pop('alter_metadata', DEFAULT_ALTER_METADATA)
|
self.alter_metadata = kwargs.pop('alter_metadata', DEFAULT_ALTER_METADATA)
|
||||||
|
@ -514,26 +520,29 @@ populated with defaults
|
||||||
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:
|
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, *args, **kwargs)
|
engine._run_visitor(visitorcallable, self, connection, **kwargs)
|
||||||
|
|
||||||
|
# TODO: reuse existing connection
|
||||||
if self.populate_default and self.default is not None:
|
if self.populate_default and self.default is not None:
|
||||||
stmt = table.update().values({self: engine._execute_default(self.default)})
|
stmt = table.update().values({self: engine._execute_default(self.default)})
|
||||||
engine.execute(stmt)
|
engine.execute(stmt)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def drop(self, table=None, *args, **kwargs):
|
def drop(self, table=None, connection=None, **kwargs):
|
||||||
"""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.
|
:param alter_metadata: If True, column will be removed from table object.
|
||||||
:type alter_metadata: bool
|
:type alter_metadata: bool
|
||||||
|
:param connection: reuse connection istead of creating new one.
|
||||||
|
:type connection: :class:`sqlalchemy.engine.base.Connection` instance
|
||||||
"""
|
"""
|
||||||
self.alter_metadata = kwargs.pop('alter_metadata', DEFAULT_ALTER_METADATA)
|
self.alter_metadata = kwargs.pop('alter_metadata', DEFAULT_ALTER_METADATA)
|
||||||
if table is not None:
|
if table is not None:
|
||||||
|
@ -542,7 +551,7 @@ populated with defaults
|
||||||
if self.alter_metadata:
|
if self.alter_metadata:
|
||||||
self.remove_from_table(self.table, unset_table=False)
|
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, connection, **kwargs)
|
||||||
if self.alter_metadata:
|
if self.alter_metadata:
|
||||||
self.table = None
|
self.table = None
|
||||||
return self
|
return self
|
||||||
|
@ -557,7 +566,7 @@ populated with defaults
|
||||||
self.table = None
|
self.table = None
|
||||||
if table.c.contains_column(self):
|
if table.c.contains_column(self):
|
||||||
table.c.remove(self)
|
table.c.remove(self)
|
||||||
|
|
||||||
# TODO: this is fixed in 0.6
|
# TODO: this is fixed in 0.6
|
||||||
def copy_fixed(self, **kw):
|
def copy_fixed(self, **kw):
|
||||||
"""Create a copy of this ``Column``, with all attributes."""
|
"""Create a copy of this ``Column``, with all attributes."""
|
||||||
|
@ -590,19 +599,21 @@ class ChangesetIndex(object):
|
||||||
|
|
||||||
__visit_name__ = 'index'
|
__visit_name__ = 'index'
|
||||||
|
|
||||||
def rename(self, name, *args, **kwargs):
|
def rename(self, name, connection=None, **kwargs):
|
||||||
"""Change the name of an index.
|
"""Change the name of an index.
|
||||||
|
|
||||||
: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.
|
:param alter_metadata: If True, Index object will be altered.
|
||||||
:type alter_metadata: bool
|
:type alter_metadata: bool
|
||||||
|
:param connection: reuse connection istead of creating new one.
|
||||||
|
:type connection: :class:`sqlalchemy.engine.base.Connection` instance
|
||||||
"""
|
"""
|
||||||
self.alter_metadata = kwargs.pop('alter_metadata', DEFAULT_ALTER_METADATA)
|
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, connection, **kwargs)
|
||||||
if self.alter_metadata:
|
if self.alter_metadata:
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue