You don't need to commit, you just need to flush.  Here's some sample code.  After the call to flush you can access the primary key that was assigned.  Note this is with SQLAlchemy v1.3.6 and Python 3.7.4.
from sqlalchemy import *
import sqlalchemy.ext.declarative
Base = sqlalchemy.ext.declarative.declarative_base()
class User(Base):
    __tablename__ = 'user'
    user_id = Column('user_id', Integer, primary_key=True)
    name = Column('name', String)
if __name__ == '__main__':
    import unittest
    from sqlalchemy.orm import *
    import datetime
    class Blah(unittest.TestCase):
        def setUp(self):
            self.engine = create_engine('sqlite:///:memory:', echo=True)
            self.sessionmaker = scoped_session(sessionmaker(bind=self.engine))
            Base.metadata.bind = self.engine
            Base.metadata.create_all()
            self.now = datetime.datetime.now()
        def test_pkid(self):
            user = User(name="Joe")
            session = self.sessionmaker()
            session.add(user)
            session.flush()
            print('user_id', user.user_id)
            session.commit()
            session.close()
    unittest.main()