diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-08-25 14:03:54 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-08-25 14:03:54 -0400 |
| commit | d6ce68727f8ad4c77cc64ac6bbc5fc17ecd2b8e3 (patch) | |
| tree | 402e29083415154f31b46da58b22b352f71aca7f /lib/sqlalchemy/orm/mapper.py | |
| parent | 00f3ca98ce24577f6a7fb40efd15bdb2d86acd26 (diff) | |
| download | sqlalchemy-d6ce68727f8ad4c77cc64ac6bbc5fc17ecd2b8e3.tar.gz | |
- The ``version_id_generator`` parameter of ``Mapper`` can now be specified
to rely upon server generated version identifiers, using triggers
or other database-provided versioning features, by passing the value
``False``. The ORM will use RETURNING when available to immediately
load the new version identifier, else it will emit a second SELECT.
[ticket:2793]
- The ``eager_defaults`` flag of :class:`.Mapper` will now allow the
newly generated default values to be fetched using an inline
RETURNING clause, rather than a second SELECT statement, for backends
that support RETURNING.
- Added a new variant to :meth:`.ValuesBase.returning` called
:meth:`.ValuesBase.return_defaults`; this allows arbitrary columns
to be added to the RETURNING clause of the statement without interfering
with the compilers usual "implicit returning" feature, which is used to
efficiently fetch newly generated primary key values. For supporting
backends, a dictionary of all fetched values is present at
:attr:`.ResultProxy.returned_defaults`.
- add a glossary entry for RETURNING
- add documentation for version id generation, [ticket:867]
Diffstat (limited to 'lib/sqlalchemy/orm/mapper.py')
| -rw-r--r-- | lib/sqlalchemy/orm/mapper.py | 105 |
1 files changed, 72 insertions, 33 deletions
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index fc80c4404..30b5ffc79 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -208,6 +208,22 @@ class Mapper(_InspectionAttr): See the section :ref:`concrete_inheritance` for an example. + :param eager_defaults: if True, the ORM will immediately fetch the + value of server-generated default values after an INSERT or UPDATE, + rather than leaving them as expired to be fetched on next access. + This can be used for event schemes where the server-generated values + are needed immediately before the flush completes. By default, + this scheme will emit an individual ``SELECT`` statement per row + inserted or updated, which note can add significant performance + overhead. However, if the + target database supports :term:`RETURNING`, the default values will be + returned inline with the INSERT or UPDATE statement, which can + greatly enhance performance for an application that needs frequent + access to just-generated server defaults. + + .. versionchanged:: 0.9.0 The ``eager_defaults`` option can now + make use of :term:`RETURNING` for backends which support it. + :param exclude_properties: A list or set of string column names to be excluded from mapping. @@ -391,9 +407,9 @@ class Mapper(_InspectionAttr): thus persisting the value to the ``discriminator`` column in the database. - See also: + .. seealso:: - :ref:`inheritance_toplevel` + :ref:`inheritance_toplevel` :param polymorphic_identity: Specifies the value which identifies this particular class as returned by the @@ -419,34 +435,44 @@ class Mapper(_InspectionAttr): can be overridden here. :param version_id_col: A :class:`.Column` - that will be used to keep a running version id of mapped entities - in the database. This is used during save operations to ensure that - no other thread or process has updated the instance during the - lifetime of the entity, else a + that will be used to keep a running version id of rows + in the table. This is used to detect concurrent updates or + the presence of stale data in a flush. The methodology is to + detect if an UPDATE statement does not match the last known + version id, a :class:`~sqlalchemy.orm.exc.StaleDataError` exception is - thrown. By default the column must be of :class:`.Integer` type, - unless ``version_id_generator`` specifies a new generation - algorithm. + thrown. + By default, the column must be of :class:`.Integer` type, + unless ``version_id_generator`` specifies an alternative version + generator. - :param version_id_generator: A callable which defines the algorithm - used to generate new version ids. Defaults to an integer - generator. Can be replaced with one that generates timestamps, - uuids, etc. e.g.:: + .. seealso:: - import uuid + :ref:`mapper_version_counter` - discussion of version counting + and rationale. - class MyClass(Base): - __tablename__ = 'mytable' - id = Column(Integer, primary_key=True) - version_uuid = Column(String(32)) + :param version_id_generator: Define how new version ids should + be generated. Defaults to ``None``, which indicates that + a simple integer counting scheme be employed. To provide a custom + versioning scheme, provide a callable function of the form:: - __mapper_args__ = { - 'version_id_col':version_uuid, - 'version_id_generator':lambda version:uuid.uuid4().hex - } + def generate_version(version): + return next_version + + Alternatively, server-side versioning functions such as triggers + may be used as well, by specifying the value ``False``. + Please see :ref:`server_side_version_counter` for a discussion + of important points when using this option. + + .. versionadded:: 0.9.0 ``version_id_generator`` supports server-side + version number generation. + + .. seealso:: + + :ref:`custom_version_counter` + + :ref:`server_side_version_counter` - The callable receives the current version identifier as its - single argument. :param with_polymorphic: A tuple in the form ``(<classes>, <selectable>)`` indicating the default style of "polymorphic" @@ -458,13 +484,9 @@ class Mapper(_InspectionAttr): indicates a selectable that will be used to query for multiple classes. - See also: - - :ref:`concrete_inheritance` - typically uses ``with_polymorphic`` - to specify a UNION statement to select from. + .. seealso:: - :ref:`with_polymorphic` - usage example of the related - :meth:`.Query.with_polymorphic` method + :ref:`with_polymorphic` - discussion of polymorphic querying techniques. """ @@ -481,9 +503,19 @@ class Mapper(_InspectionAttr): self.order_by = order_by self.always_refresh = always_refresh - self.version_id_col = version_id_col - self.version_id_generator = version_id_generator or \ - (lambda x: (x or 0) + 1) + + if isinstance(version_id_col, MapperProperty): + self.version_id_prop = version_id_col + self.version_id_col = None + else: + self.version_id_col = version_id_col + if version_id_generator is False: + self.version_id_generator = False + elif version_id_generator is None: + self.version_id_generator = lambda x: (x or 0) + 1 + else: + self.version_id_generator = version_id_generator + self.concrete = concrete self.single = False self.inherits = inherits @@ -1406,6 +1438,13 @@ class Mapper(_InspectionAttr): _validate_polymorphic_identity = None @_memoized_configured_property + def _version_id_prop(self): + if self.version_id_col is not None: + return self._columntoproperty[self.version_id_col] + else: + return None + + @_memoized_configured_property def _acceptable_polymorphic_identities(self): identities = set() |
