summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/dialects/mssql/base.py26
-rw-r--r--lib/sqlalchemy/engine/__init__.py10
-rw-r--r--lib/sqlalchemy/engine/threadlocal.py12
-rw-r--r--lib/sqlalchemy/schema.py6
-rw-r--r--lib/sqlalchemy/types.py24
5 files changed, 77 insertions, 1 deletions
diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py
index 290cd1019..facfdd754 100644
--- a/lib/sqlalchemy/dialects/mssql/base.py
+++ b/lib/sqlalchemy/dialects/mssql/base.py
@@ -114,6 +114,32 @@ compatibiility level information. Because of this, if running under
a backwards compatibility mode SQAlchemy may attempt to use T-SQL
statements that are unable to be parsed by the database server.
+Triggers
+--------
+
+SQLAlchemy by default uses OUTPUT INSERTED to get at newly
+generated primary key values via SEQUENCE columns. MS-SQL does not
+allow the usage of OUTPUT INSERTED on tables that have triggers.
+To disable the usage of OUTPUT INSERTED on a per-table basis,
+specify ``implicit_returning=False`` to each :class:`.Table`
+which has sequences::
+
+ Table('mytable', metadata,
+ Column('id', Integer, primary_key=True),
+ # ...,
+ implicit_returning=False
+ )
+
+Declarative form::
+
+ class MyClass(Base):
+ # ...
+ __table_args__ = {'implicit_returning':False}
+
+
+This option can also be specified enginewide using the
+``implicit_returning=False`` argument on :func:`.create_engine`.
+
Known Issues
------------
diff --git a/lib/sqlalchemy/engine/__init__.py b/lib/sqlalchemy/engine/__init__.py
index aebf35436..e33dff53b 100644
--- a/lib/sqlalchemy/engine/__init__.py
+++ b/lib/sqlalchemy/engine/__init__.py
@@ -175,6 +175,16 @@ def create_engine(*args, **kwargs):
be applied to all connections. See
:meth:`~sqlalchemy.engine.base.Connection.execution_options`
+ :param implicit_returning=True: When ``False``, the RETURNING
+ feature of the database, if available, will not be used
+ to fetch newly generated primary key values. This applies
+ to those backends which support RETURNING or a compatible
+ construct, including Postgresql, Firebird, Oracle, Microsoft
+ SQL Server. The default behavior is to use a compatible RETURNING
+ construct when a single-row INSERT statement is emitted with no
+ existing returning() clause in order to fetch newly generated
+ primary key values.
+
:param label_length=None: optional integer value which limits
the size of dynamically generated column labels to that many
characters. If less than 6, labels are generated as
diff --git a/lib/sqlalchemy/engine/threadlocal.py b/lib/sqlalchemy/engine/threadlocal.py
index 2ce0922bf..d4d0488a9 100644
--- a/lib/sqlalchemy/engine/threadlocal.py
+++ b/lib/sqlalchemy/engine/threadlocal.py
@@ -71,16 +71,28 @@ class TLEngine(base.Engine):
if not hasattr(self._connections, 'trans'):
self._connections.trans = []
self._connections.trans.append(self.contextual_connect().begin_twophase(xid=xid))
+ return self
def begin_nested(self):
if not hasattr(self._connections, 'trans'):
self._connections.trans = []
self._connections.trans.append(self.contextual_connect().begin_nested())
+ return self
def begin(self):
if not hasattr(self._connections, 'trans'):
self._connections.trans = []
self._connections.trans.append(self.contextual_connect().begin())
+ return self
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, traceback):
+ if type is None:
+ self.commit()
+ else:
+ self.rollback()
def prepare(self):
if not hasattr(self._connections, 'trans') or \
diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py
index df7dbace0..f4b214061 100644
--- a/lib/sqlalchemy/schema.py
+++ b/lib/sqlalchemy/schema.py
@@ -1648,7 +1648,11 @@ class CheckConstraint(Constraint):
__visit_name__ = property(__visit_name__)
def copy(self, **kw):
- return CheckConstraint(self.sqltext, name=self.name)
+ return CheckConstraint(self.sqltext,
+ name=self.name,
+ initially=self.initially,
+ deferrable=self.deferrable,
+ _create_rule=self._create_rule)
class ForeignKeyConstraint(Constraint):
"""A table-level FOREIGN KEY constraint.
diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py
index 613dad82a..a2ecafaa8 100644
--- a/lib/sqlalchemy/types.py
+++ b/lib/sqlalchemy/types.py
@@ -189,6 +189,24 @@ class TypeEngine(AbstractType):
return util.constructor_copy(self, cls, **kw)
def _coerce_compared_value(self, op, value):
+ """Suggest a type for a 'coerced' Python value in an expression.
+
+ Given an operator and value, gives the type a chance
+ to return a type which the value should be coerced into.
+
+ The default behavior here is conservative; if the right-hand
+ side is already coerced into a SQL type based on its
+ Python type, it is usually left alone.
+
+ End-user functionality extension here should generally be via
+ :class:`.TypeDecorator`, which provides more liberal behavior in that
+ it defaults to coercing the other side of the expression into this
+ type, thus applying special Python conversions above and beyond those
+ needed by the DBAPI to both ides. It also provides the public method
+ :meth:`.TypeDecorator.coerce_compared_value` which is intended for
+ end-user customization of this behavior.
+
+ """
_coerced_type = _type_map.get(type(value), NULLTYPE)
if _coerced_type is NULLTYPE or _coerced_type._type_affinity \
is self._type_affinity:
@@ -491,6 +509,8 @@ class TypeDecorator(TypeEngine):
return self
def _coerce_compared_value(self, op, value):
+ """See :meth:`.TypeEngine._coerce_compared_value` for a description."""
+
return self.coerce_compared_value(op, value)
def copy(self):
@@ -1326,6 +1346,8 @@ class _Binary(TypeEngine):
# end Py2K
def _coerce_compared_value(self, op, value):
+ """See :meth:`.TypeEngine._coerce_compared_value` for a description."""
+
if isinstance(value, basestring):
return self
else:
@@ -1826,6 +1848,8 @@ class Interval(_DateAffinity, TypeDecorator):
return Interval
def _coerce_compared_value(self, op, value):
+ """See :meth:`.TypeEngine._coerce_compared_value` for a description."""
+
return self.impl._coerce_compared_value(op, value)