SQLAlchemy clone table row with relations

2019-01-25 18:30发布

问题:

Following on from this question SQLAlchemy: Modification of detached object.

This makes a copy of the object fine, but it loses any many-to-many relationships the original object had. Is there a way to copy the object and any many-to-many relationships as well?

Cheers!

回答1:

I got this to work by walking the object graph and doing the expunge(), make_transient() and id = None steps on each object in the graph as described in SQLAlchemy: Modification of detached object.



回答2:

Here is my sample code. The agent has at most one campaign.

from sqlalchemy.orm.session import make_transient
def clone_agent(id):
    s = app.db.session
    agent = s.query(Agent).get(id)
    c = None
    # you need get child before expunge agent, otherwise the children will be empty
    if agent.campaigns:
        c = agent.campaigns[0]
        s.expunge(c)
        make_transient(c)
        c.id = None
    s.expunge(agent)
    agent.id = None
    # I have unique constraint on the following column.
    agent.name = agent.name + '_clone'
    agent.externalId = - agent.externalId # find a number that not in db.

    make_transient(agent)
    s.add(agent)
    s.commit() # commit so the agent will save to database and get an id
    if c:
        assert agent.id
        c.agent_id = agent.id # attatch child to parent. agent_id is a foreign key
        s.add(c)
        s.commit()


标签: sqlalchemy