sqlalchemy flush () y se inserta id?

Quiero hacer algo como esto:

f = Foo(bar='x') session.add(f) session.flush() # do additional queries using f.id before commit() print f.id # should be not None session.commit() 

Pero f.id es None cuando lo bash. ¿Cómo puedo conseguir que esto funcione?

-Dan

Su código de muestra debería haber funcionado como está. Sqlalchemy debería proporcionar un valor para f.id , asumiendo que es una columna de clave primaria autogenerada. Los atributos de la clave principal se completan inmediatamente dentro del proceso de descarga () a medida que se generan y no se requiere una llamada a commit (). Entonces, la respuesta aquí se encuentra en los detalles de su asignación, si hay alguna peculiaridad del backend en uso (por ejemplo, SQLite no genera valores enteros para una clave primaria compuesta) y / o lo que dice el SQL emitido cuando encender el eco.

Acabo de encontrar el mismo problema y, después de las pruebas, he encontrado que NINGUNA de estas respuestas son suficientes.

Actualmente, o desde sqlalchemy .6+, hay una solución muy simple (no sé si existe en la versión anterior, aunque creo que sí existe):

sesion.refresh ()

Entonces, tu código se vería así:

 f = Foo(bar=x) session.add(f) session.flush() # At this point, the object f has been pushed to the DB, # and has been automatically assigned a unique primary key id f.id # is None session.refresh(f) # refresh updates given object in the session with its state in the DB # (and can also only refresh certain attributes - search for documentation) f.id # is the automatically assigned primary key ID given in the database. 

Así es como hacerlo.

Gracias a todos Resolví mi problema modificando el mapeo de columnas. Para mí, autoincrement=True es obligatorio.

origen: id = Column('ID', Integer, primary_key=True, nullable=False)

después de la modificación: id = Column('ID', Integer, primary_key=True, autoincrement=True, nullable=True)

entonces session.flush()
print(f.id)
session.flush()
print(f.id)

esta bien

a diferencia de la respuesta dada por dpb, una actualización no es necesaria. una vez que se vacíe, puede acceder al campo de identificación, sqlalchemy actualiza automáticamente la identificación que se genera automáticamente en el backend

Encontré este problema y calculé la razón exacta después de algunas investigaciones, mi modelo fue creado con id como campo entero y en mi formulario el id estaba representado con un campo oculto (ya que no quería mostrar el id en mi formulario). El campo oculto está representado de forma predeterminada como un texto. una vez que cambié el formulario a integerfield con widget = hiddenInput ()) se resolvió el problema.

Una vez tuve un problema con haber asignado 0 a id antes de llamar al método session.add . La base de datos asignó correctamente el id, pero no se recuperó el id correcto de la sesión después de session.flush() .

Debería intentar usar session.save_or_update(f) lugar de session.add(f) .