On 09/11/2010 04:31 AM, alex wrote: > On 09/10/2010 05:41 PM, Michael Bayer wrote: >> On Sep 10, 2010, at 4:13 AM, alex wrote: >> >>> hello friends, >>> >>> as sqlite has recently introduced support for on delete/update cascade, >>> i'd like to implement the passive_* functionality for this driver too. >>> >>> please give me a hint where to start. >> passive_delete and passive_update are database agnostic and only apply to >> what effects the ORM can expect from the underlying schema, just use them >> normally. >> > thanks a lot for your response michael. > i spent a little time to make a more isolated test case, and it works with > sa+orm, but not with elixir, that seems to forget to pass the passive_deletes. > i'm further inquiring there, in a hope to make a patch. > > best regards, > alex one further step took me closer to the problem. it happens with declarative too. i'm attaching 3 scripts for comparison: one made with regular orm, one with elixir and one with declarative. the same problem with elixir and declarative. haven't tested on other rdbms.
-- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalch...@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.
from sqlalchemy import (MetaData, Table, Column, Integer, String, ForeignKey, create_engine, ForeignKeyConstraint) from sqlalchemy.orm import scoped_session, sessionmaker, relation from sqlalchemy.ext.declarative import declarative_base engine = create_engine("sqlite:///:memory:", echo=True) Base = declarative_base(bind=engine) class MyClass(Base): __tablename__ = 'mytable' id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(50)) # children = relation('MyOtherClass', backref='parent') def __repr__(self): return '<MyClass %s, "%s">' % ("None" if self.id is None else str(self.id), self.name) class MyOtherClass(Base): __tablename__ = 'myothertable' id = Column(Integer, primary_key=True, autoincrement=True) parent_id = Column(Integer, ForeignKey('mytable.id', ondelete="CASCADE")) parent = relation('MyClass', backref='children', passive_deletes=True) name = Column(String(50)) 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) Base.metadata.create_all(engine) session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine)) 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
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): using_options(tablename='mytable') 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): using_options(tablename='myothertable') 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) 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) }) 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