hello friends,

there seems to be a flaw in elixir with cascade deletes.

i have a program that does it with sqlalchemy orm, and a similar one to do it
with elixir.
instead of deleting the elixir program only nulls the keys in the child.

the programs are attached.

best regards,
alex

-- 
You received this message because you are subscribed to the Google Groups 
"SQLElixir" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sqlelixir?hl=en.

from sqlalchemy import (MetaData, Table, Column, Integer, String, ForeignKey,
                        create_engine, ForeignKeyConstraint)
from sqlalchemy.orm import (mapper, relationship, sessionmaker)

from elixir import *


engine = create_engine("sqlite:///:memory:", echo=True)

metadata.bind = engine

connection = engine.connect()
connection.execute('PRAGMA foreign_keys = ON;')


class MyClass(Entity):
    id = Field(Integer, primary_key=True, autoincrement=True)
    name = Field(String(20))
#    children = OneToMany('MyOtherClass', ondelete="CASCADE", passive_deletes=True)

    def __repr__(self):
        return '<MyClass %s, "%s">' % ("None" if self.id is None else str(self.id), self.name)

class MyOtherClass(Entity):
    id = Field(Integer, primary_key=True, autoincrement=True)
    name = Field(String(20))
    parent = ManyToOne('MyClass', backref='children', colname='parent_id', ondelete="CASCADE", passive_deletes=True)

    def __repr__(self):
        return '<MyOtherClass %s, %s, "%s">' % ("None" if self.parent_id is None else str(self.parent_id), "None" if self.id is None else str(self.id), self.name)

#cascade="all, delete-orphan", 

setup_all()
create_all()


alex = MyClass(name='alex')
pisi = MyClass(name='pisi')

print alex, pisi

#session.commit()
session.flush()

print alex, pisi

alexdagan = MyOtherClass(parent=alex, name='dagan')
alexshaked = MyOtherClass(parent=alex, name='shaked')
pisidagan = MyOtherClass(parent=pisi, name='dagan')
pisishaked = MyOtherClass(parent=pisi, name='shaked')

#session.commit()
session.flush()

shaked1 = session.query(MyOtherClass).filter_by(parent_id=1, name=u'shaked')

session.delete(alex)

#session.commit()
session.flush()


for my in session.query(MyClass).all():
    print my
for my in session.query(MyOtherClass).all():
    print my

from sqlalchemy import (MetaData, Table, Column, Integer, String, ForeignKey,
                        create_engine, ForeignKeyConstraint)
from sqlalchemy.orm import (mapper, relationship, sessionmaker)


meta = MetaData()

engine = create_engine("sqlite:///:memory:", echo=True)

connection = engine.connect()
connection.execute('PRAGMA foreign_keys = ON;')

meta.create_all(engine)

mytable = Table('mytable', meta,
    Column('id', Integer, primary_key=True, autoincrement=True),
    Column('name', String(20)),
    )

myothertable = Table('myothertable', meta,
    Column('id', Integer, primary_key=True, autoincrement=True),
    Column('parent_id', Integer),
    Column('name', String(20)),
    ForeignKeyConstraint(['parent_id'], ['mytable.id'], ondelete="CASCADE"),
    )

class OldStyleBaseClass(object):
    """A base class for our SA object that do not use declarative, This simply provides keyword access for init and a decent print output, original recipe from http://www.sqlalchemy.org/trac/wiki/UsageRecipes/GenericOrmBaseClass""";
    def __init__(self, **kw):
        for key in kw:
            if not key.startswith('_'):
                setattr(self, key, kw[key])

    def __repr__(self):
        attrs = []
        for key in self.__dict__:
            if not key.startswith('_'):
                attrs.append((key, getattr(self, key)))
        return self.__class__.__name__ + '(' + ', '.join(x[0] + '=' +
                                            repr(x[1]) for x in attrs) + ')'

    def to_dict(self):
        """Generate a JSON-style dict from a record."""
        data = dict([(key, getattr(self, key)) 
                     for key in self.__dict__ if not key.startswith('_')])
        return data

class MyClass(OldStyleBaseClass):
    pass

class MyOtherClass(OldStyleBaseClass):
    pass

mapper(MyOtherClass, myothertable)

mapper(MyClass, mytable, properties={
    'children': relationship(MyOtherClass, backref='parent', passive_deletes=True)
})
#cascade="all, delete-orphan", 
#

meta.create_all(engine)
session = sessionmaker(engine, expire_on_commit=False)()

alex = MyClass(name='alex')
pisi = MyClass(name='pisi')

session.add_all([
    alex, pisi
])

print alex, pisi

session.flush()

session.add_all([
    MyOtherClass(parent=alex, name='dagan'),
    MyOtherClass(parent=alex, name='shaked'),
    MyOtherClass(parent=pisi, name='dagan'),
    MyOtherClass(parent=pisi, name='shaked'),
])

session.flush()

shaked1 = session.query(MyOtherClass).filter_by(parent_id=1, name=u'shaked')

session.delete(alex)

session.flush()

for my in session.query(MyClass).all():
    print my
for my in session.query(MyOtherClass).all():
    print my

Reply via email to