Improved identity implementation
This commit is contained in:
@@ -4,6 +4,7 @@ from .functions import (
|
|||||||
batch_fetch,
|
batch_fetch,
|
||||||
defer_except,
|
defer_except,
|
||||||
escape_like,
|
escape_like,
|
||||||
|
identity,
|
||||||
primary_keys,
|
primary_keys,
|
||||||
render_statement,
|
render_statement,
|
||||||
render_expression,
|
render_expression,
|
||||||
@@ -55,6 +56,7 @@ __all__ = (
|
|||||||
escape_like,
|
escape_like,
|
||||||
generates,
|
generates,
|
||||||
generic_relationship,
|
generic_relationship,
|
||||||
|
identity,
|
||||||
instrumented_list,
|
instrumented_list,
|
||||||
merge,
|
merge,
|
||||||
primary_keys,
|
primary_keys,
|
||||||
|
@@ -201,16 +201,41 @@ def identity(obj):
|
|||||||
always returns the identity even if object is still in transient state (
|
always returns the identity even if object is still in transient state (
|
||||||
new object that is not yet persisted into database).
|
new object that is not yet persisted into database).
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
from sqlalchemy_utils import identity
|
||||||
|
|
||||||
|
|
||||||
|
user = User(name=u'John Matrix')
|
||||||
|
session.add(user)
|
||||||
|
identity(user) # None
|
||||||
|
inspect(user).identity # None
|
||||||
|
|
||||||
|
session.flush() # User now has id but is still in transient state
|
||||||
|
|
||||||
|
identity(user) # (1,)
|
||||||
|
inspect(user).identity # None
|
||||||
|
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
identity(user) # (1,)
|
||||||
|
inspect(user).identity # (1, )
|
||||||
|
|
||||||
|
|
||||||
|
.. versionadded: 0.21.0
|
||||||
|
|
||||||
:param obj: SQLAlchemy declarative model object
|
:param obj: SQLAlchemy declarative model object
|
||||||
"""
|
"""
|
||||||
id_ = []
|
id_ = []
|
||||||
for attr in obj._sa_class_manager.values():
|
for column in sa.inspect(obj.__class__).columns:
|
||||||
prop = attr.property
|
if column.primary_key:
|
||||||
if isinstance(prop, sa.orm.ColumnProperty):
|
id_.append(getattr(obj, column.name))
|
||||||
column = prop.columns[0]
|
|
||||||
if column.primary_key:
|
if all(value is None for value in id_):
|
||||||
id_.append(getattr(obj, column.name))
|
return None
|
||||||
return tuple(id_)
|
else:
|
||||||
|
return tuple(id_)
|
||||||
|
|
||||||
|
|
||||||
def naturally_equivalent(obj, obj2):
|
def naturally_equivalent(obj, obj2):
|
||||||
|
@@ -13,4 +13,11 @@ class TestIdentity(TestCase):
|
|||||||
self.Building = Building
|
self.Building = Building
|
||||||
|
|
||||||
def test_for_transient_class_without_id(self):
|
def test_for_transient_class_without_id(self):
|
||||||
assert identity(self.Building()) == (None,)
|
assert identity(self.Building()) is None
|
||||||
|
|
||||||
|
def test_for_transient_class_with_id(self):
|
||||||
|
building = self.Building(name=u'Some building')
|
||||||
|
self.session.add(building)
|
||||||
|
self.session.flush()
|
||||||
|
|
||||||
|
assert identity(building) == (building.id, )
|
||||||
|
Reference in New Issue
Block a user