Tenemos un modelo con un campo JSON donde se insertan indicadores de usuario. La inserción funciona como se esperaba, pero al eliminar ciertos indicadores, permanecen en el campo y los cambios no se conservan en la base de datos.
Tenemos el siguiente método en nuestro modelo:
def del_flag(self, key): if self.user_flags is None or not key in self.user_flags: return False else: del self.user_flags[key] db.session.commit() return TrueLa base de datos es postgres y usamos el dialecto de campo SQLalchemy JSON para el tipo de campo. ¿Algún consejo sobre esto?
Si está utilizando Postgres < 9.4, no puede actualizar el campo JSON directamente. Necesita la función flag_modified para informar el cambio a SQLAlchemy:
from sqlalchemy.orm.attributes import flag_modified model.data['key'] = 'New value' flag_modified(model, "data") session.add(model) session.commit()Estoy usando el campo JSON y me referí a continuación en el documento.
https://docs.sqlalchemy.org/en/13/core/type_basics.html?highlight=json#sqlalchemy.types.JSON
Muestra cómo hacer que el campo JSON-dict sea mutable. (El valor predeterminado es inmutable)
Me gusta esto..
from sqlalchemy.ext.mutable import MutableDict from sqlalchemy import Column, Integer, JSON class TableABC(Base): __tablename__ = 'table_abc' id = Column(Integer, primary_key=True) info = Column(MutableDict.as_mutable(JSON))Entonces podría actualizar el campo json como ORM.
Mi problema fue hacer referencia al objeto de fila devuelto por SQLAlchemy al crear la nueva fila. por ejemplo, esto no funciona :
row = db.session.query(SomeTable).filter_by(id=someId).first() print(row.details) newDetails = row.details newDetails['key'] = 'new data' row.details = newDetails db.session.commit()pero crear un nuevo dict funciona
row = db.session.query(SomeTable).filter_by(id=someId).first() print(row.details) newDetails = dict(row.details) newDetails['key'] = 'new data' row.details = newDetails db.session.commit() aviso dict(row.details)