is there any sort of find_or_create query?

90 views
Skip to first unread message

CoolAJ86

unread,
Dec 28, 2009, 9:40:20 PM12/28/09
to sqlalchemy
If I have an object User in rails with attributes first, last, and
password I can do something like this

user = {:first => 'John', :last => 'Doe'} # a dict-like object
user = Users.find_or_create(user)

is there any such convenience method in sqlalchemy?

AJ ONeal

unread,
Dec 28, 2009, 11:18:11 PM12/28/09
to sqlalchemy
It looks like the answer to my question is no.

Is there any add-on (Elixer or whatever) which has a shortcut method like what I'm asking?


I did find that "insert_or_update" is not the solution.
I also found an appropriate, but longer way to read or create:

page = Session.query(Page).filter(Page.url == url, Page.body==body).first() 
if not page: 
  page = Page(url = url, body=body) 
  session.save(page)

If you know the primary key identifiers of the object, you may also use merge():
page = Page(<primary key identifiers>) 
  persisted_page = Session.merge(page)

the latter will do the same thing automatically as the former (SQLA does not use IntegrityErrors to query the database).

AJ ONeal


--

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



AJ ONeal

unread,
Dec 28, 2009, 11:28:38 PM12/28/09
to sqlalchemy
Actually the answer is yes.

merge() reconciles the current state of an instance and its associated children with existing data in the database, and returns a copy of the instance associated with the session. Usage is as follows:


merged_object = session.merge(existing_object)

When given an instance, it follows these steps:

  • It examines the primary key of the instance. If it’s present, it attempts to load an instance with that primary key (or pulls from the local identity map).
  • If there’s no primary key on the given instance, or the given primary key does not exist in the database, a new instance is created.
  • The state of the given instance is then copied onto the located/newly created instance.
  • The operation is cascaded to associated child items along the merge cascade. Note that all changes present on the given instance, including changes to collections, are merged.
  • The new instance is returned.

Generically the pattern is called: insert_or_update
SQLAlchemy calls it: merge
Rails calls it: find_or_create
Symfony implements it as: setNew(false) and then save()
MySql calls it: insert on duplicate update

AJ ONeal

Nebur

unread,
Dec 29, 2009, 1:37:21 PM12/29/09
to sqlalchemy
AJ, thanks for the monologue ;-)
It reads like a good overview.
Reply all
Reply to author
Forward
0 new messages