Creating a new instance using an identity key/pk?

19 views
Skip to first unread message

Gerald Thibault

unread,
Aug 27, 2014, 6:17:02 PM8/27/14
to sqlal...@googlegroups.com
I have a pretty simple goal, so simple I probably don't even need example code.

I have 2 classes, and I want to pull the identity key from an instance of one class, and use the values to create an instance of the second, without requiring (or introspecting) things like the PK names, FK names linking them, etc. Something like:

instance1 = Class1()
cls, vals = identity_key(instance=instance1)
instance2 = Class2.from_identity_key(vals) # that method doesn't exist

I am trying to do this without requiring any of the PK column names or FK info linking the 2 tables together (they are a 1-to-1 relationship). given only an instance of Class1 and the class "Class2", I want to create the instance of Class2.

Is this possible? Is there a way to "reverse" identity_key, so instead of instance -> (cls, vals)  I could do (cls, vals) -> instance?

JT

Michael Bayer

unread,
Aug 27, 2014, 7:58:50 PM8/27/14
to sqlal...@googlegroups.com
OK well how to the primary key attributes of Class1 and Class2 relate? If Class1’s primary key columns are “a”, “b”, and Class2’s primary key columns are, “id”, how is that mapping done? are we assuming same number of columns in the PK of both, in the same order, or same names, or what?


Gerald Thibault

unread,
Aug 27, 2014, 9:17:55 PM8/27/14
to sqlal...@googlegroups.com
The pks are named differently in every case, which is why i was looking for a way that didn't involve use of keys at all. For every case, the length of the pks are the same, and the columns comprising the key are in the same order.

The mapping is done by a standard relationship, but I was thinking I wouldn't need the mapping at all if i am just pulling and pushing a pk value. The name of the relationship is different in every case.

Gerald Thibault

unread,
Aug 27, 2014, 9:24:38 PM8/27/14
to sqlal...@googlegroups.com
Also, this might help to clarify my goal, this is my current working code that accomplishes the desired result, but with more introspection than I was hoping for. If there isn't something easier, this will work.


# instance1 is an instance of Class1, i want to create Class2 with the same pk

keys = [key.name for key in class_mapper(Class2).primary_key]
cls, values = identity_key(instance=instance1)
kwargs = dict(zip(keys, values))
instance2 = Class2(**kwargs)

I'm basically looking for a shortcut for that, if it exists.

JT

Michael Bayer

unread,
Aug 30, 2014, 1:43:33 AM8/30/14
to sqlal...@googlegroups.com
not a shorter way, but more correct in case you have columns mapped to different names:

mp1 = inspect(instance1)
mp2 = inspect(Class2)

Class2(**dict(
zip(
mp2.get_property_by_column(col).key for col in mp2.primary_key,
mp1.primary_key_from_instance(instance1)
)
))

JT Thibault

unread,
Aug 30, 2014, 9:50:29 PM8/30/14
to sqlal...@googlegroups.com
Awesome, thanks for that. 


--
You received this message because you are subscribed to a topic in the Google Groups "sqlalchemy" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/sqlalchemy/d3mMjDLlqfY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to sqlalchemy+...@googlegroups.com.
To post to this group, send email to sqlal...@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages