pythonpython-3.xponyorm

How to get current inserted auto-incremented primary key in PonyORM?


I am using the following code to get create a new row in the database, using PonyORM:

transportTypes = TransportTypes(
    TransportTypeTitle=data['TransportTypeTitle'], 
    Description=data['Description'],
    LatestUpdateDate=datetime.now()
)

However, the primary key is still set to None. The primary key of the table is auto-incremented, how can I get the generated primary key of the new record?


Solution

  • You need to explicitly flush the entity, by calling its Entity.flush() method:

    Save the changes made to this object to the database. Usually Pony saves changes automatically and you don’t need to call this method yourself. One of the use cases when it might be needed is when you want to get the primary key value of a newly created object which has autoincremented primary key before commit.

    Bold emphasis mine

    For your example, that would be:

    transportTypes = TransportTypes(
        TransportTypeTitle=data['TransportTypeTitle'], 
        Description=data['Description'],
        LatestUpdateDate=datetime.now()
    )
    transportTypes.flush()
    print(transportTypes.id)
    

    Another option would be to explicitly commit first. From the Saving objects in the database section:

    If you need to get the primary key value of a newly created object, you can do commit() manually within the db_session() in order to get this value[.]

    # [...]
    
    @db_session
    def handler(email):
        c = Customer(email=email)
        # c.id is equal to None
        # because it is not assigned by the database yet
        commit()
        # the new object is persisted in the database
        # c.id has the value now
        print(c.id)
    

    So, when using db_session as a context manager, which commits automatically when the context exits, you could use:

    with db_session:
        transportTypes = TransportTypes(
            TransportTypeTitle=data['TransportTypeTitle'], 
            Description=data['Description'],
            LatestUpdateDate=datetime.now()
        )
    
    # context has been exited, the session has been committed
    # and the identity map has been cleared, so accessing attributes loads
    # them fresh from the database
    print(transportTypes.id)