Modelling of parent/children relationships on entity level

This commit is contained in:
Fabio Manganiello 2022-11-28 21:36:00 +01:00
parent 0e0c90f0f2
commit 0edd73690b
Signed by untrusted user: blacklight
GPG key ID: D90FBA7F76362774
2 changed files with 26 additions and 2 deletions

View file

@ -8,6 +8,7 @@ import pkgutil
from sqlalchemy import ( from sqlalchemy import (
Boolean, Boolean,
Column, Column,
ForeignKey,
Index, Index,
Integer, Integer,
String, String,
@ -16,7 +17,7 @@ from sqlalchemy import (
UniqueConstraint, UniqueConstraint,
inspect as schema_inspect, 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.common.db import Base
from platypush.message import JSONAble from platypush.message import JSONAble
@ -38,6 +39,12 @@ class Entity(Base):
description = Column(String) description = Column(String)
type = Column(String, nullable=False, index=True) type = Column(String, nullable=False, index=True)
plugin = Column(String, nullable=False) plugin = Column(String, nullable=False)
parent_id = Column(
Integer,
ForeignKey(f'{__tablename__}.id', ondelete='CASCADE'),
nullable=True,
)
data = Column(JSON, default=dict) data = Column(JSON, default=dict)
meta = Column(JSON, default=dict) meta = Column(JSON, default=dict)
is_read_only = Column(Boolean, default=False) is_read_only = Column(Boolean, default=False)
@ -50,6 +57,19 @@ class Entity(Base):
DateTime(timezone=False), default=datetime.utcnow(), onupdate=datetime.utcnow() 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) UniqueConstraint(external_id, plugin)
__table_args__ = ( __table_args__ = (

View file

@ -6,6 +6,7 @@ from time import time
from typing import Iterable, List, Optional from typing import Iterable, List, Optional
from sqlalchemy import and_, or_ from sqlalchemy import and_, or_
from sqlalchemy.exc import InvalidRequestError
from sqlalchemy.orm import Session, make_transient from sqlalchemy.orm import Session, make_transient
from platypush.context import get_bus, get_plugin from platypush.context import get_bus, get_plugin
@ -258,7 +259,10 @@ class EntitiesEngine(Thread):
session.commit() session.commit()
for e in entities: for e in entities:
session.expunge(e) try:
session.expunge(e)
except InvalidRequestError:
pass
with self._entities_cache_lock: with self._entities_cache_lock:
for entity in entities: for entity in entities: