Improved identity implementation

This commit is contained in:
Konsta Vesterinen
2013-10-30 14:32:38 +02:00
parent c1a725eccb
commit 77bade0457
3 changed files with 42 additions and 8 deletions

View File

@@ -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,

View File

@@ -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):

View File

@@ -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, )