Mike Bayer avatar Mike Bayer committed 7f99921

- added a handy multi-use "identity_key()" method to Session, allowing
the generation of identity keys for primary key values, instances,
and rows, courtesy Daniel Miller

Comments (0)

Files changed (2)

       worked anyway), but also query.selectfirst(), query.selectone() which
       will be used as is (i.e. no query is compiled). works similarly to
       sending the results to instances().
+
+    - added a handy multi-use "identity_key()" method to Session, allowing
+      the generation of identity keys for primary key values, instances,
+      and rows, courtesy Daniel Miller
       
     - added "refresh-expire" cascade [ticket:492].  allows refresh() and
       expire() calls to propigate along relationships.

lib/sqlalchemy/orm/session.py

             self.save(merged)
         return merged
 
+    def identity_key(self, *args, **kwargs):
+        """Get an identity key
+
+        Valid call signatures:
+
+        identity_key(class_, ident, entity_name=None)
+            class_ - mapped class
+            ident - primary key, if the key is composite this is a tuple
+            entity_name - optional entity name. May be given as a
+                positional arg or as a keyword arg.
+
+        identity_key(instance=instance)
+            instance - object instance (must be given as a keyword arg)
+
+        identity_key(row=row, class=class_, entity_name=None)
+            row - result proxy row (must be given as a keyword arg)
+        """
+        if args:
+            kw = {}
+            if len(args) == 2:
+                class_, ident = args
+                entity_name = kwargs.pop("entity_name", None)
+                assert not kwargs, ("unknown keyword arguments: %s"
+                    % (kwargs.keys(),))
+            else:
+                assert len(args) == 3, ("two or three positional args are "
+                    "accepted, got %s" % len(args))
+                class_, ident, entity_name = args
+            mapper = _class_mapper(class_, entity_name=entity_name)
+            return mapper.instance_key_from_primary_key(ident,
+                entity_name=entity_name)
+        else:
+            try:
+                instance = kwargs.pop("instance")
+            except KeyError:
+                row = kwargs.pop("row")
+                class_ = kwargs.pop("class")
+                entity_name = kwargs.pop("entity_name", None)
+                assert not kwargs, ("unknown keyword arguments: %s"
+                    % (kwargs.keys(),))
+                mapper = _class_mapper(class_, entity_name=entity_name)
+                return mapper.identity_key_from_row(row)
+            else:
+                assert not kwargs, ("unknown keyword arguments: %s"
+                    % (kwargs.keys(),))
+                mapper = _object_mapper(instance)
+                return mapper.identity_key_from_instance(instance)
+
     def _save_impl(self, object, **kwargs):
         if hasattr(object, '_instance_key'):
             if not self.identity_map.has_key(object._instance_key):
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.