(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
[email protected]
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users