Michael Bayer ha scritto:

the original mapping essentially expressed this relationship:

   A <--  cascade="all, delete-orphan" --> B

in both directions.  What that means is, there cannot be an A with no B
in the database, and there cannot be a B with no A in the database,
i.e. its either A<->B or both will be deleted.  its like an oxygen
molecule, or something.

what you need to do is decide which of A and B can exist on its own
without a parent relationship.  since you want to delete rows from B
and not A, that would indicate that the mapping should be:

mapper(A, a)
mapper(
    B, b,
    properties={
        'a': relation(
            A, backref=backref('b', lazy=False, uselist=False,
                               cascade='all, delete-orphan'),
            uselist=False
            )
        }
    )

i.e. the "delete-orphan" cascade is only in the direction from A->B.
the cascade from B->A is left at its default value of "save-update", so
delete operations dont propigate from B's to A's.


Sorry, I still have problems.
Here is the code I'm using:


from sqlalchemy import *


db = create_engine('postgres://manlio:[EMAIL PROTECTED]/test', echo=True)


metadata = BoundMetaData(db)
a = Table(
    'a', metadata,
    Column('x', String),
    Column('y', String),
    PrimaryKeyConstraint('x', 'y')
    )

b = Table(
    'b', metadata,
    Column('x', String),
    Column('y', String),
    Column('z', String),
    PrimaryKeyConstraint('x', 'y'),
    ForeignKeyConstraint(['x', 'y'], ['a.x', 'a.y'], ondelete='CASCADE')
    )

metadata.create_all()


class A(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

class B(object):
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z


mapper(A, a)
mapper(
    B, b,
    properties={
        'a': relation(
            A, backref=backref('b', lazy=False, uselist=False,
                               cascade='all, delete-orphan'),
            uselist=False
            )
        }
    )


try:
    #### 1
    conn = db.connect()
    trans = conn.begin()
    sess = create_session(bind_to=conn)

    o = A('1', '2')
    o.b = B(o.x, o.y, '3')
    sess.save(o)

    sess.flush()
    sess.close()
    trans.commit()
    conn.close()


    #### 2
    conn = db.connect()
    trans = conn.begin()
    sess = create_session(bind_to=conn)

    sess.update(o)
    print o.b.z
    del o.b
    #sess.delete(o.b)
    #o.b = None

    sess.flush()
    sess.close()
    trans.commit()
    conn.close()

    #### 3
    print o.b
    s = a.select()
    print conn.execute(s).fetchall()
finally:
    metadata.drop_all(tables=[b])
    metadata.drop_all(tables=[a])




The error is:

Traceback (most recent call last):
  File "alchemy.py", line 82, in ?
    print o.b
  File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/attributes.py",
line 48, in __get__
    return self.get(obj)
  File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/attributes.py",
line 205, in get
    value = callable_()
  File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/strategies.py",
line 204, in lazyload
    raise exceptions.InvalidRequestError("Parent instance %s is not
bound to a Session, and no contextual session is established; lazy load
operation of attribute '%s' cannot proceed" % (instance.__class__,
self.key))
sqlalchemy.exceptions.InvalidRequestError: Parent instance <class
'__main__.A'> is not bound to a Session, and no contextual session is
established; lazy load operation of attribute 'b' cannot proceed



Thanks and regards  Manlio Perillo


--~--~---------~--~----~------------~-------~--~----~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to