Hello,

I am experimenting with a pattern where records hold the table name
and record id of the next record in any other table, chaining records
in different tables. This works, but I can't figure out how to clean
op references to the next record in another table when I delete a
record (the pattern does not use foreign keys in the normal sense).
The code is:

=====================================

from sqlalchemy import *
from sqlalchemy.orm.session import sessionmaker
from sqlalchemy.ext.declarative import declarative_base,
declared_attr, DeclarativeMeta
#---------------------------------------------------------------------------
Base = declarative_base()
reg = dict()
engine = create_engine('sqlite:///:memory:', echo=False)
Session = sessionmaker(bind = engine)
#---------------------------------------------------------------------------

class chainmeta(DeclarativeMeta):
#---------------------------------------------------------------------------
    class Base(object):
        session = Session()
        @declared_attr
        def __tablename__(cls):
            return cls.__name__

        id = Column(Integer, primary_key = True)
        next_table = Column(String(64))
        next_id = Column(Integer) #in table with name stored in
next_table!

        def __init__(self, data, next = None):
            self.data = data
            self.prev = None
            self.next = next
            self.session.add(self)
            self.session.flush()

        def _getnext(self):
            if self.next_table and self.next_id:

                return
self.session.query(reg[self.next_table]).filter(self.next_id ==
reg[self.next_table].id).one()
            else: return None

        def _setnext(self, next):
            if next:
                if self.next:
                    self.next.prev = None
                self.next_table = next.__tablename__
                self.next_id = next.id
                next.prev = self
            elif self.next:
                self.next.prev = None
                self.next_table = None
                self.next_id = None

        def _delnext(self):
            self.next.prev = None
            self.next_table = None
            self.next_id = None

        next = property(_getnext, _setnext, _delnext)

        def __repr__(self):
            out = "type: " + type(self).__name__ + "["
            for name in self.__dict__:
                out += name + ", "
            out += "]"
            return out
#---------------------------------------------------------------------------
    def __new__(mcls, name, coltype):
        return DeclarativeMeta.__new__(mcls, name, (chainmeta.Base,
Base),{"data": Column(coltype, nullable = False)})
    def __init__(cls, name, coltype):
        reg[name] = cls
        return DeclarativeMeta.__init__(cls, name, (chainmeta.Base,
Base),{})
#---------------------------------------------------------------------------
if __name__ == '__main__':
    Base.metadata.drop_all(engine)
    session = chainmeta.Base.session = Session()

    Ni = chainmeta("Ni", Integer)
    Nb = chainmeta("Nb", Boolean)
    Nt = chainmeta("Nt", String(200))
    Base.metadata.create_all(engine)

    ni1 = Ni(5)
    ni2 = Ni(12)
    nb1 = Nb(True)
    nb2 = Nb(False)
    nt1 = Nt("text in nt1")
    nt2 = Nt("text in nt2")
    ni1.next = ni2
    ni2.next = nb1
    nb1.next = nb2
    nb2.next = nt1
    nt1.next = nt2
    nt2.next = ni1 #circular
    print "OBJECTS"
    n = ni1
    count = 0
    print "nexts: ................."
    while n and count < 10:
        print n.data
        count += 1
        n = n.next
    n = ni1
    count = 0
    print "prevs: ................."
    while n and count < 10:
        print n.data
        count += 1
        n = n.prev
    print
"-----------------------------------------------------------------------------------"
    nts = session.query(Nt).all()
    print "QUERIES"
    for nt in nts:
        print nt.data
    print "+++++++++++++++++++++"
    print session.query(Ni).filter(Ni.next_id ==
nb1.id).first().data


=====================================

This might seem to have no reasonable us case, but it is something I
want to use in a more complicated pattern later on. Basically the
question is, how can I remove a record and have no next or prev
pointing to it in other objects or records (without adding some sort
of external controller)?

Cheers, Lars


-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to