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 [email protected].
To unsubscribe from this group, send email to
[email protected].
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