Hello Mike,

Here's a simple test case script that creates tables in sqlite (memory).

To resume, we have "site_table" table and "option_table" objects as a 
many-to-many relationship through a secondary "weak" table 
"options_has_sites".

I want to be able to:
- delete a "site" without deleting the attached options.
- delete an "option" without deleting the attached sites.
- make sure the weak table is beeing cleaned up correctly depending if a 
site or an option has been removed.

Regards,
-- 
Alexandre CONRAD



Michael Bayer wrote:

> the rows in the M2M table should be deleted automatically.    it  
> *might* require that your instances are present in the session but  
> its not supposed to.  can you make me a short test case for this  
> one ?  its not the first time ive heard about it.
> 
> technically you can just put ON DELETE CASCADE on the tables too but  
> id like to fix this issue.
> 
> 
> On Mar 16, 2007, at 12:19 PM, Alexandre CONRAD wrote:
> 
> 
>>Humm, this doesn't help as if a site is deleted, it deletes the  
>>options
>>that where related to that option.
>>
>>I want to be able to:
>>- delete an option without deleting a site
>>- delete a site without deleting an option
>>
>>just delete (clean up) the related rows inside the weak
>>"options_has_sites" table.
>>
>>I just can't figure it out...
>>
>>
>>Michael Bayer wrote:
>>
>>
>>>youd need to add some "delete" cascades to your relationship, maybe
>>>on just the backref (using the backref() function), e.g.
>>>
>>>option_mapper = assign_mapper(ctx, Option, option_table,
>>>      properties={
>>>          'sites':relation(Site, backref=backref("options",
>>>cascade="save-update, delete"),
>>>secondary=options_has_sites, cascade="save-update"),
>>>      },
>>>      order_by=option_table.c.name,
>>>)
>>>
>>>
>>>
>>>On Mar 16, 2007, at 10:38 AM, Alexandre CONRAD wrote:
>>>
>>>
>>>
>>>>Hello,
>>>>
>>>>I have a many-to-many relation between an option table and a site
>>>>table.
>>>>
>>>>Deleting an option correctly deletes the related rows in
>>>>"options_has_sites" table.
>>>>
>>>>But when I delete a site, I have some orphan rows in the
>>>>"options_has_sites" table. How can I avoid this ?
>>>>
>>>>
>>>># SITE TABLE -----------
>>>>site_table = Table('sites', meta,
>>>>    Column('id', Integer, primary_key=True),
>>>>    Column('name', Unicode(20), nullable=False, unique=True),
>>>>)
>>>>
>>>>class Site(object):
>>>>    pass
>>>>
>>>>site_mapper = assign_mapper(ctx, Site, site_table,
>>>>    order_by=site_table.c.name,
>>>>)
>>>>
>>>>
>>>># OPTION TABLE ------------
>>>>option_table = Table('options', meta,
>>>>    Column('id', Integer, primary_key=True),
>>>>    Column('name', Unicode(20), unique=True, nullable=False),
>>>>)
>>>>
>>>>options_has_sites = Table('sites_has_options', meta,
>>>>    Column('id_site', None, ForeignKey('sites.id'),
>>>>primary_key=True),
>>>>    Column('id_option', None, ForeignKey('options.id'),
>>>>primary_key=True),
>>>>)
>>>>
>>>>class Option(object):
>>>>    pass
>>>>
>>>>option_mapper = assign_mapper(ctx, Option, option_table,
>>>>    properties={
>>>>        'sites':relation(Site, backref="options",
>>>>secondary=options_has_sites, cascade="save-update"),
>>>>    },
>>>>    order_by=option_table.c.name,
>>>>)
>>>>
>>>>
>>>>Should I play with backref() ?
>>>>
>>>>Regards,
>>>>-- 
>>>>Alexandre CONRAD
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>
>>-- 
>>Alexandre CONRAD - TLV FRANCE
>>Research & Development
>>
>>
>>
> 
> 
> > 
> 
> 
> ---------------------------------------------------------------------------------------------------
> Texte inséré par Platinum 2007:
> 
>  S'il s'agit d'un mail indésirable (SPAM), cliquez sur le lien suivant pour 
> le reclasser : http://127.0.0.1:6083/Panda?ID=pav_31925&SPAM=true
> ---------------------------------------------------------------------------------------------------
> 
> 




--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

from sqlalchemy import *

meta = DynamicMetaData()

# Sites
site_table = Table('sites', meta,
    Column('id', Integer, primary_key=True),
    Column('name', Unicode(20), nullable=False, unique=True),
    Column('email', Unicode(100)),
)

class Site(object):
    pass

site_mapper = mapper(Site, site_table,
    order_by=site_table.c.name,
)


# Options
option_table = Table('options', meta,
    Column('id', Integer, primary_key=True),
    Column('name', Unicode(20), unique=True, nullable=False),
    Column('description', Unicode(40)),
)

options_has_sites = Table('options_has_sites', meta,
    Column('id_site', None, ForeignKey('sites.id'), primary_key=True),
    Column('id_option', None, ForeignKey('options.id'), primary_key=True),
)

class Option(object):
    def __repr__(self):
        return "Option: %s" % repr(self.name)

option_mapper = mapper(Option, option_table,
    properties={
        'sites':relation(Site, backref="options", secondary=options_has_sites, 
cascade="save-update"),
    },
    order_by=option_table.c.name,
)

meta.connect("sqlite://", echo=True)
meta.create_all()

# Make session.
session = create_session()

# Inject sites and options.
for i in range(1, 4):
    o = Option()
    o.name, o.description = "opt%d" % i, "This is option %d" % i
    session.save(o)
    s = Site()
    s.name, s.email = "site%d" % i, "[EMAIL PROTECTED]" % i
    session.save(s)

session.flush()
session.clear()

print """\n### Now, let's query for site 1."""
s = session.query(Site).get(1)
opts = session.query(Option).select()
print """\n### Add options from 1 to 3 to the site."""
s.options = opts[0:3] # Put option 1, 2 and 3
session.flush()
session.clear()

print """\n### Now, let's query for site 1 again."""
s = session.query(Site).get(1)
print """\n### Check the site has the options 1, 2 and 3."""
print s.options, "!!!!!!!we should have opt 1, 2 and 3 here!!!!!!!"
session.clear()

print """\n### If it has, we should have pairs of (id_site, id_opt) in 
options_has_sites."""
print options_has_sites.select().execute().fetchall(), "!!!!!!!we should have 3 
pairs here!!!!!!!"

print """\n### Now, let's query for option 1."""
o = session.query(Option).get(1)
print """\n### Now remove option 1."""
session.delete(o)
session.flush()
session.clear()

print """\n### Now, let's query for site 1 again."""
s = session.query(Site).get(1)
print """\n### Check what options has the site. Option 1 should be removed from 
sites."""
print s.options, "!!!!!!!!!we should only have opt2 and opt3 in 
here!!!!!!!!!!!!!"
session.clear()

print """\n### Now check that the row (id_site, id_opt) for option 1 should be 
removed from table "options_has_sites"."""
print options_has_sites.select().execute().fetchall(), "!!!!!!!we should only 
have 2 pairs now that opt1 was removed!!!!!!!"

print """\n### Let's query for site 1."""
s = session.query(Site).get(1)
print """\n### Now let's delete the site."""
session.delete(s)
session.flush()
session.clear()

print """\n### We should still have option 2 and 3, even if the site was 
deleted."""
print session.query(Option).select()

print """\n### The rows (id_site, id_opt) for option 2 and 3 of the site should 
be removed from "options_has_sites"."""
print options_has_sites.select().execute().fetchall(), "!!!!!We want this 
cleaned up and empty now that we have removed the site. How to do that 
??!!!!!!!!!"

Reply via email to