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 to 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 is 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 # Attach child to parent (agent_id is a foreign key)
s.add(c)
s.commit()