>> Why does Session.merge only look at primary key and not all unique
>> keys?
>
> Well the theory of operation regarding merge() is based on that of
> the identity map, which is linked to object/row identity.
> Consider that it also cascades along relationship paths.  It would
> be a difficult operation to define if it had to choose among
> multiple ways to determine the "identity" of each object along the
> cascade chain.

Ok.  That certainly makes sense for following relationships in the
merge (and in general).  But for the basic existence checking that is
required in the first step(s) of the merge to figure out whether the
object being merged already exists or not, it does not seem
unreasonable for it to check all unique keys.  ie: in your docs you
say the first merge step is "It examines the primary key of the
instance".  Can't it be "It checks any provided unique elements of the
instance".  From that point, normal/sensible identity map rules could
resume for cascade.  "Is a" checking is not the same as "is related
to" checking, which is clearly nuttier.

Although... you do mention later that ORM level has no knowledge of
"unique" attributes, so perhaps this is also impossible?  Is the
"unique = True" kwarg on the Column not kept anywhere?  Is it just
used for table creation and then turfed?

>> Leaving aside some irritating DBMS restrictions on PKs and some
>> automatic indexing that tends to happen, the PK is not fundamentally
>> different than other unique keys
>
> It is fundamentally different in that a database row within a
> reasonable schema has only one "identity".  The usage of surrogate
> primary keys perhaps pollutes this concept to some degree.

Ok again... but you also agree that the use of surrogate keys is
standard (and some say "necessary") practice.  In the case of Sqlite
(as in my example), adding this surrogate key automatically makes the
schema "unreasonable" because you now need to have the primary key as
the meaningless surrogate key (single id column), and the natural key
ends up being relegated to just another unique index.  Unfortunately,
the latter renders the object/table useless for use with the useful
session.merge() function.  I don't recall the details, but I think
there may be a similar PostgreSQL limitation regarding autoincrements
as well.

> for some recent insight into my epic battle with time consumption,
> see http://techspot.zzzeek.org/2010/12/12/a-tale-of-three-profiles

Great link/post!  Seeing successful optimizations is always good, and
the writeup is quite informative.

Regarding RunSnakeRun, I've used it as well and like it.  However, I'm
a bit of a resolution junkie and the box frames in RunSnakeRun's
visual output are limited in how they will squish all the box borders
together.  If you haven't given kcachegrind a shot yet for viewing
cProfile results, you might want to give it a trial run as the visual
output is a better representation of timing scale, and the viewing is
more powerful as well (if resolution is too weak if an argument).
Some tips to get it to work well for python are here:
http://stackoverflow.com/questions/1896032/using-cprofile-results-with-kcachegrind

> The generic "insert if not exists" pattern that is extensible to
> whatever attributes you want is at:
> http://www.sqlalchemy.org/trac/wiki/UsageRecipes/UniqueObject

Thanks for the example...  I would have been worried about how
fiddling with the __new__ constructor would interfere with query
loads, but that example shows how to make it work.

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to