How to do an upsert with SqlAlchemy?

前端 未结 7 1522
别跟我提以往
别跟我提以往 2020-12-08 01:37

I have a record that I want to exist in the database if it is not there, and if it is there already (primary key exists) I want the fields to be updated to the current state

7条回答
  •  抹茶落季
    2020-12-08 02:16

    I use a "look before you leap" approach:

    # first get the object from the database if it exists
    # we're guaranteed to only get one or zero results
    # because we're filtering by primary key
    switch_command = session.query(Switch_Command).\
        filter(Switch_Command.switch_id == switch.id).\
        filter(Switch_Command.command_id == command.id).first()
    
    # If we didn't get anything, make one
    if not switch_command:
        switch_command = Switch_Command(switch_id=switch.id, command_id=command.id)
    
    # update the stuff we care about
    switch_command.output = 'Hooray!'
    switch_command.lastseen = datetime.datetime.utcnow()
    
    session.add(switch_command)
    # This will generate either an INSERT or UPDATE
    # depending on whether we have a new object or not
    session.commit()
    

    The advantage is that this is db-neutral and I think it's clear to read. The disadvantage is that there's a potential race condition in a scenario like the following:

    • we query the db for a switch_command and don't find one
    • we create a switch_command
    • another process or thread creates a switch_command with the same primary key as ours
    • we try to commit our switch_command

提交回复
热议问题