(sorry if this message appears twice ...)

Hi,

I'm using SQLAlchemy 2.2 in a mod_python application, with a "home made" 
handler.
Here are my tables / mappers definitions:

###########################

# application/models/__init__.py

from datetime import datetime

from sqlalchemy import *

from application.models.invasive import Invasive, InvasiveName, 
InvasiveGroup, InvasiveSubGroup
from application.models.language import Language
from application.models.habitat import Habitat
from application.models.origin import Origin
from application.models.user import User, UserPermission

from application import configuration

db_engine = create_engine(configuration.main.DB_DSN, encoding='utf-8')

meta = BoundMetaData(db_engine)

languages = Table('languages', meta,
   Column('id', Integer, primary_key=True),
   Column('iso_code', String(2)),
   Column('language', String(100)))
  users = Table('users', meta,
   Column('id', Integer, primary_key=True),
   Column('login', String(50)),
   Column('password', String(32)),
   Column('first_name', String(100)),
   Column('name', String(100)),
   Column('email', String(100)))

user_permissions = Table('user_permissions', meta,
   Column('user_id', Integer, ForeignKey('users.id'), primary_key=True),
   Column('perm_invasive', String(50)),
   Column('perm_users', String(50)))

invasives = Table('invasives', meta,
   Column('id', Integer, primary_key=True),
   Column('added', DateTime, default=datetime.now()),
   Column('modified', DateTime, default=datetime.now(), 
onupdate=datetime.now()),
   Column('scientific_name', String(200)),
   Column('geographic_range', String(3)),
   Column('trend', String(30)),
   Column('nat_reproduction', Boolean),
   Column('nat_dense_populations', Boolean),
   Column('nat_dispersal_capacity', Boolean),
   Column('nat_natural_habitats', Boolean),
   Column('impact_global', Boolean),
   Column('impact_competition', Boolean),
   Column('impact_predation', Boolean),
   Column('impact_hybridisation', Boolean),
   Column('impact_disease_transmission', Boolean),
   Column('impact_ecosystem_disruption', Boolean),
   Column('impact_health', Boolean),
   Column('impact_economic', Boolean),
   Column('first_obs_belgium', Smallinteger),
   Column('first_obs_flanders', Smallinteger),
   Column('first_obs_wallonia', Smallinteger),
   Column('intr_fishing', Boolean),
   Column('intr_hunting', Boolean),
   Column('intr_fur', Boolean),
   Column('intr_culture', Boolean),
   Column('intr_petornamental', Boolean),
   Column('intr_canals', Boolean),
   Column('intr_accidental', Boolean),
   Column('intr_deliberated', Boolean),
   Column('black_lists_belg', String(3)),
   Column('black_lists_sebi', Boolean),
   Column('black_lists_eppo', Boolean),
   Column('status', Integer),
   Column('group_id', Integer, ForeignKey('invasive_groups.id')),
   Column('subgroup_id', Integer, ForeignKey('invasive_subgroups.id')))

invasive_groups = Table('invasive_groups', meta,
   Column('id', Integer, primary_key=True),
   Column('group_name', String(100)))

invasive_subgroups = Table('invasive_subgroups', meta,
   Column('id', Integer, primary_key=True),
   Column('subgroup_name', String(100)))

invasive_names = Table('invasive_names', meta,
   Column('name', String(200)),
   Column('language_id', Integer, ForeignKey('languages.id'), 
primary_key=True),
   Column('invasive_id', Integer, ForeignKey('invasives.id'), 
primary_key=True))
  invasive_habitats = Table('invasive_habitats', meta,
   Column('invasive_id', Integer, ForeignKey('invasives.id'), 
primary_key=True),
   Column('habitat_id', Integer, ForeignKey('habitats.id'), 
primary_key=True))

invasive_origins = Table('invasive_origins', meta,
   Column('invasive_id', Integer, ForeignKey('invasives.id'), 
primary_key=True),
   Column('origin_id', Integer, ForeignKey('origins.id'), 
primary_key=True))

habitats = Table('habitats', meta,
   Column('id', Integer, primary_key=True),
   Column('habitat', String(100)))

origins = Table('origins', meta,
   Column('id', Integer, primary_key=True),
   Column('origin', String(100)))

mapper(Origin, origins)

mapper(Habitat, habitats)

mapper(InvasiveName, invasive_names)

mapper(Invasive, invasives, properties = {
   'names' : relation(InvasiveName, backref='invasive', cascade='all, 
delete-orphan'),
   'habitats' : relation(Habitat, secondary=invasive_habitats, lazy=False),
   'origins' : relation(Origin, secondary=invasive_origins, lazy=False)
   }
)

mapper(InvasiveGroup, invasive_groups, properties = {
   'invasives' : relation(Invasive, backref='group', lazy=False)
   }
)

mapper(InvasiveSubGroup, invasive_subgroups, properties = {
   'invasives' : relation(Invasive, backref='subgroup', lazy=False)
   }
)

mapper(User, users)

mapper(Language, languages, properties = {
   'invasive_names' : relation(InvasiveName, backref='language', 
cascade='all, delete-orphan')
   }
)

mapper(UserPermission, user_permissions, properties = {
   'user' : relation(User,
       backref=backref('permission', uselist=False), cascade='all, 
delete-orphan', lazy=False)
   }
)

###########################

As you can see, I have a table "invasives" which is mapped to the 
Invasive object. This table has a "many-to-many" relation with the 
"habitats" table through the "invasive_habitats" table. So an invasive 
can have multiple habitats. When I load an  Invasive object from the 
database with a session.query(Invasive).get(<pk>) I have their habitats 
through the "habitats" properties ('habitats' : relation(Habitat, 
secondary=invasive_habitats, lazy=False)), so this is OK and works fine. 
The problem I have is when I want to update the habitats of an Invasive. 
The values comes from an html <form> in a mod_python Session object 
("params" in the following). So I do something like :

# application/controllers/invasive.py

invasive_object = session.query(Invasive).get(168)

=> The result is send to the HTML form for update
=> The user submit the modification

Then I did the following :

for habitat in self.params.getlist('invasive_habitats'):
   invasive_object.habitats.append(query_habitat.get(habitat))

which fails because SQLAlchemy does not update or delete the rows in the 
"invasive_habitats" table. In place it try to insert a new record which 
fail of course :

INSERT INTO invasive_habitats (invasive_id, habitat_id) VALUES (168, 1) 
'INSERT INTO invasive_habitats (invasive_id, habitat_id) VALUES 
(%(invasive_id)s, %(habitat_id)s)' [{'invasive_id': 168, 'habitat_id': 
1}, {'invasive_id': 168, 'habitat_id': 2}]

I tried a clear() method like:

invasive_object.habitats.clear()
for habitat in self.params.getlist('invasive_habitats'):
   invasive_object.habitats.append(query_habitat.get(habitat))

but it doesn't work ...
What did I wrong ?

In advance, thanks !

Julien

-- 
Julien Cigar
Belgian Biodiversity Platform
http://www.biodiversity.be
Université Libre de Bruxelles
Campus de la Plaine CP 257
Bâtiment NO, Bureau 4 N4 115C (Niveau 4)
Boulevard du Triomphe, entrée ULB 2
B-1050 Bruxelles
office: [EMAIL PROTECTED]
home: [EMAIL PROTECTED]



_______________________________________________
Sqlalchemy-users mailing list
Sqlalchemy-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users

Reply via email to