Nous avons un modèle avec un champ JSON dans lequel les drapeaux utilisateur sont insérés. L'insertion fonctionne comme prévu, mais lors de la suppression de certains indicateurs, ils restent dans le champ et les modifications ne sont pas conservées dans la base de données.
Nous avons la méthode suivante dans notre modèle:
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 True
La base de données est postgres et nous utilisons le dialecte de champ SQLalchemy JSON pour le type de champ. Un conseil à ce sujet?
Si vous utilisez Postgres <9.4, vous ne pouvez pas mettre à jour le champ JSON directement. Vous avez besoin de la fonction flag_modified pour signaler la modification à SQLAlchemy:
from sqlalchemy.orm.attributes import flag_modified
model.data['key'] = 'New value'
flag_modified(model, "data")
session.add(model)
session.commit()
Mon problème faisait référence à l'objet de ligne renvoyé par SQLAlchemy lors de la création de la nouvelle ligne. par exemple. cela ne fonctionne pas:
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()
mais créer un nouveau dict ça marche
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()
remarque dict(row.details)
J'utilise le champ JSON et j'ai fait référence au document ci-dessous.
https://docs.sqlalchemy.org/en/13/core/type_basics.html?highlight=json#sqlalchemy.types.JSON
Il montre comment rendre le champ JSON-dict mutable. (La valeur par défaut est immuable)
comme ça..
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))
Ensuite, je pourrais mettre à jour le champ json comme ORM.