Update SQLAlchemy

This commit is contained in:
Ruud
2013-06-14 11:00:06 +02:00
parent 267ecfacab
commit 4aa6700ceb
124 changed files with 6500 additions and 5207 deletions
+96 -19
View File
@@ -1,5 +1,5 @@
# orm/collections.py
# Copyright (C) 2005-2012 the SQLAlchemy authors and contributors <see AUTHORS file>
# Copyright (C) 2005-2013 the SQLAlchemy authors and contributors <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php
@@ -111,27 +111,62 @@ import weakref
from sqlalchemy.sql import expression
from sqlalchemy import schema, util, exc as sa_exc
__all__ = ['collection', 'collection_adapter',
'mapped_collection', 'column_mapped_collection',
'attribute_mapped_collection']
__instrumentation_mutex = util.threading.Lock()
class _SerializableColumnGetter(object):
def __init__(self, colkeys):
self.colkeys = colkeys
self.composite = len(colkeys) > 1
class _PlainColumnGetter(object):
"""Plain column getter, stores collection of Column objects
directly.
Serializes to a :class:`._SerializableColumnGetterV2`
which has more expensive __call__() performance
and some rare caveats.
"""
def __init__(self, cols):
self.cols = cols
self.composite = len(cols) > 1
def __reduce__(self):
return _SerializableColumnGetter, (self.colkeys,)
return _SerializableColumnGetterV2._reduce_from_cols(self.cols)
def _cols(self, mapper):
return self.cols
def __call__(self, value):
state = instance_state(value)
m = _state_mapper(state)
key = [
m._get_state_attr_by_column(state, state.dict, col)
for col in self._cols(m)
]
if self.composite:
return tuple(key)
else:
return key[0]
class _SerializableColumnGetter(object):
"""Column-based getter used in version 0.7.6 only.
Remains here for pickle compatibility with 0.7.6.
"""
def __init__(self, colkeys):
self.colkeys = colkeys
self.composite = len(colkeys) > 1
def __reduce__(self):
return _SerializableColumnGetter, (self.colkeys,)
def __call__(self, value):
state = instance_state(value)
m = _state_mapper(state)
key = [m._get_state_attr_by_column(
state, state.dict,
state, state.dict,
m.mapped_table.columns[k])
for k in self.colkeys]
if self.composite:
@@ -139,6 +174,48 @@ class _SerializableColumnGetter(object):
else:
return key[0]
class _SerializableColumnGetterV2(_PlainColumnGetter):
"""Updated serializable getter which deals with
multi-table mapped classes.
Two extremely unusual cases are not supported.
Mappings which have tables across multiple metadata
objects, or which are mapped to non-Table selectables
linked across inheriting mappers may fail to function
here.
"""
def __init__(self, colkeys):
self.colkeys = colkeys
self.composite = len(colkeys) > 1
def __reduce__(self):
return self.__class__, (self.colkeys,)
@classmethod
def _reduce_from_cols(cls, cols):
def _table_key(c):
if not isinstance(c.table, expression.TableClause):
return None
else:
return c.table.key
colkeys = [(c.key, _table_key(c)) for c in cols]
return _SerializableColumnGetterV2, (colkeys,)
def _cols(self, mapper):
cols = []
metadata = getattr(mapper.local_table, 'metadata', None)
for (ckey, tkey) in self.colkeys:
if tkey is None or \
metadata is None or \
tkey not in metadata:
cols.append(mapper.local_table.c[ckey])
else:
cols.append(metadata.tables[tkey].c[ckey])
return cols
def column_mapped_collection(mapping_spec):
"""A dictionary-based collection type with column-based keying.
@@ -155,10 +232,10 @@ def column_mapped_collection(mapping_spec):
from sqlalchemy.orm.util import _state_mapper
from sqlalchemy.orm.attributes import instance_state
cols = [c.key for c in [
expression._only_column_elements(q, "mapping_spec")
for q in util.to_list(mapping_spec)]]
keyfunc = _SerializableColumnGetter(cols)
cols = [expression._only_column_elements(q, "mapping_spec")
for q in util.to_list(mapping_spec)
]
keyfunc = _PlainColumnGetter(cols)
return lambda: MappedCollection(keyfunc)
class _SerializableAttrGetter(object):
@@ -632,8 +709,8 @@ class CollectionAdapter(object):
"""
if initiator is not False and item is not None:
return self.attr.fire_append_event(
self.owner_state,
self.owner_state.dict,
self.owner_state,
self.owner_state.dict,
item, initiator)
else:
return item
@@ -648,8 +725,8 @@ class CollectionAdapter(object):
"""
if initiator is not False and item is not None:
self.attr.fire_remove_event(
self.owner_state,
self.owner_state.dict,
self.owner_state,
self.owner_state.dict,
item, initiator)
def fire_pre_remove_event(self, initiator=None):
@@ -660,8 +737,8 @@ class CollectionAdapter(object):
"""
self.attr.fire_pre_remove_event(
self.owner_state,
self.owner_state.dict,
self.owner_state,
self.owner_state.dict,
initiator=initiator)
def __getstate__(self):