From 0edd73690bc586c09322e0dcf689d7005e0db75b Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Mon, 28 Nov 2022 21:36:00 +0100 Subject: [PATCH] Modelling of parent/children relationships on entity level --- platypush/entities/_base.py | 22 +++++++++++++++++++++- platypush/entities/_engine.py | 6 +++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/platypush/entities/_base.py b/platypush/entities/_base.py index e69f7c77a2..da56b68195 100644 --- a/platypush/entities/_base.py +++ b/platypush/entities/_base.py @@ -8,6 +8,7 @@ import pkgutil from sqlalchemy import ( Boolean, Column, + ForeignKey, Index, Integer, String, @@ -16,7 +17,7 @@ from sqlalchemy import ( UniqueConstraint, inspect as schema_inspect, ) -from sqlalchemy.orm import ColumnProperty +from sqlalchemy.orm import ColumnProperty, Mapped, backref, relationship from platypush.common.db import Base from platypush.message import JSONAble @@ -38,6 +39,12 @@ class Entity(Base): description = Column(String) type = Column(String, nullable=False, index=True) plugin = Column(String, nullable=False) + parent_id = Column( + Integer, + ForeignKey(f'{__tablename__}.id', ondelete='CASCADE'), + nullable=True, + ) + data = Column(JSON, default=dict) meta = Column(JSON, default=dict) is_read_only = Column(Boolean, default=False) @@ -50,6 +57,19 @@ class Entity(Base): DateTime(timezone=False), default=datetime.utcnow(), onupdate=datetime.utcnow() ) + parent: Mapped['Entity'] = relationship( + 'Entity', + remote_side=[id], + uselist=False, + lazy=True, + backref=backref( + 'children', + remote_side=[parent_id], + uselist=True, + cascade='all, delete-orphan', + ), + ) + UniqueConstraint(external_id, plugin) __table_args__ = ( diff --git a/platypush/entities/_engine.py b/platypush/entities/_engine.py index 4a06f21c75..dfc57e16de 100644 --- a/platypush/entities/_engine.py +++ b/platypush/entities/_engine.py @@ -6,6 +6,7 @@ from time import time from typing import Iterable, List, Optional from sqlalchemy import and_, or_ +from sqlalchemy.exc import InvalidRequestError from sqlalchemy.orm import Session, make_transient from platypush.context import get_bus, get_plugin @@ -258,7 +259,10 @@ class EntitiesEngine(Thread): session.commit() for e in entities: - session.expunge(e) + try: + session.expunge(e) + except InvalidRequestError: + pass with self._entities_cache_lock: for entity in entities: