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