Hi, 

so, I'm currently facing this issue, where I would like to do some calls to 
an external service, when my object has been deleted within a flush. 
For this operation to occur, I need the id from my model object, but also 
the id from the parent of the parent object model. There are cases, where I 
am unable to access them (I guess, depending of the order of the execution) 
and I am unsure on what to do next.

So if you're willing to give me some advice, would be awesome. 

Here is a dummy model:

from sqlalchemy import event

from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, backref, relationship

Base = declarative_base()


#########################################################################################
# MODEL
#########################################################################################
class House(Base):
    __tablename__ = 'house'
    id = Column(Integer, primary_key=True)
    rooms = relationship("Room",
                         backref=backref("house", lazy="joined"),
                         cascade='all, delete-orphan')


class Room(Base):
    __tablename__ = 'room'
    id = Column(Integer, primary_key=True)
    house_id = Column(Integer, ForeignKey('house.id'))
    beds = relationship("Bed",
                        backref=backref("room", lazy="joined"),
                        cascade='all, delete-orphan')


class Bed(Base):
    __tablename__ = 'bed'
    id = Column(Integer, primary_key=True)
    room_id = Column(Integer, ForeignKey('room.id'))


#########################################################################################
# CONFIG
#########################################################################################
def setup():
    engine = create_engine("sqlite:///foo.db", echo=True)

    Base.metadata.bind = engine
    Base.metadata.create_all(engine)

    SessionFactory = sessionmaker(
        bind=engine
    )

    event.listen(SessionFactory, 'deleted_to_detached', 
listener_bed_has_been_removed)

    return SessionFactory


def listener_bed_has_been_removed(session, instance):
    if type(instance) is not Bed:
        return

    bed_id = instance.id
    house_id = instance.room.house.id  # this is NOT ALWAYS there. Depending on 
the order of the execution I guess

    print("execute the service call to external service here bed_id {}, 
house_id {}".format(bed_id, house_id))
    

 

So my question(s):

   - Is there a clean way to always acces this parent's parent attribute?
      - If not, would be starting a new session and query it from the event 
      handler be an option? (is it not dangerous, because it seems to work)
         - Additional quirk, I am working within a transaction manager 
         (pyramid_tm) and ZopeTransactionExtension()
      
Thanks!


More information about the system:

SQLAlchemy 1.1.13

Python 3.5

Postgres 9.6

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to