Hi again! I've solved using an association proxy and an attribute
mapped collection.
Here's the solution
class SottocontoCE(DeclarativeBase):
__tablename__ = 'sottoconto_ce'
id = Column(Integer, primary_key=True)
nome = Column(Unicode(255), unique=True, nullable=False)
descrizione = Column(Unicode(255)
def _crea_associazione_ce_to_ce(sottoconto, sottoconto_proporzionale):
return SottocontiCEProporzionaliCEPerAttivita
(sottoconto=sottoconto,
sottoconto_proporzionale=sottoconto_proporzionale)
class Attivita(DeclarativeBase):
__tablename__ = 'attivita'
#
{Columns
id = Column(Integer, primary_key=True)
nome = Column(Unicode(255), unique=True, nullable=False)
descrizione = Column(Unicode(255))
ce_to_ce=relation('SottocontiCEProporzionaliCEPerAttivita',
collection_class=attribute_mapped_collection
('sottoconto'),
cascade='all, delete-orphan')
proporzionalita_ce_to_ce = association_proxy('ce_to_ce',
'sottoconto_proporzionale', creator=_crea_associazione_ce_to_ce)
class SottocontiCEProporzionaliCEPerAttivita(DeclarativeBase):
__tablename__ = 'sottoconti_ce_proporzionali_ce_per_attivita'
sottoconto_id = Column(Integer, ForeignKey('sottoconto_ce.id'),
primary_key=True)
attivita_id = Column(Integer, ForeignKey('attivita.id'),
primary_key=True)
sottoconto_proporzionale_id=Column(Integer, ForeignKey
('sottoconto_ce.id'))
attivita=relation('Attivita')
sottoconto=relation('SottocontoCE',
primaryjoin=sottoconto_id==SottocontoCE.id,
foreign_keys=[sottoconto_id])
sottoconto_proporzionale=relation('SottocontoCE',
primaryjoin=sottoconto_proporzionale_id==SottocontoCE.id,
foreign_keys=
[sottoconto_proporzionale_id])
def __init__(self, sottoconto=None, attivita=None,
sottoconto_proporzionale=None):
self.sottoconto=sottoconto
self.attivita=attivita
self.sottoconto_proporzionale=sottoconto_proporzionale
and here some output to be more clear
>>> sc1 = DBSession.query(SottocontoCE).filter_by(id=1).one
()
>>> sc2 = DBSession.query(SottocontoCE).filter_by(id=2).one
()
>>> sc3 = DBSession.query(SottocontoCE).filter_by(id=3).one
()
>>> att = DBSession.query(Attivita).filter_by(id=1).one
()
>>> att.proporzionalita_ce_to_ce[sc1] =
sc2
>>> att.proporzionalita_ce_to_ce[sc2] =
sc3
>>> DBSession.add
(att)
>>> DBSession.flush
()
>>> att.proporzionalita_ce_to_ce.pop
(sc1)
Acqua
>>> DBSession.add
(att)
>>> DBSession.flush
()
>>>
att.proporzionalita_ce_to_ce
{Acqua:
gas}
>>> att.proporzionalita_ce_to_ce[sc1] =
sc2
>>>
att.proporzionalita_ce_to_ce
{Energia Elettrica: Acqua, Acqua:
gas}
>>> DBSession.add
(att)
>>> DBSession.flush
()
>>> for k in att.proporzionalita_ce_to_ce.keys
():
... att.proporzionalita_ce_to_ce.pop
(k)
Acqua
gas
>>>
att.proporzionalita_ce_to_ce
{}
>>> DBSession.add
(att)
>>> DBSession.flush
()
>>> att.proporzionalita_ce_to_ce[sc1] =
sc2
>>> att.proporzionalita_ce_to_ce[sc2] =
sc3
>>> DBSession.add
(att)
>>> DBSession.flush
()
>>>
att.proporzionalita_ce_to_ce
{Energia Elettrica: Acqua, Acqua: gas}
On 24 Set, 14:43, Simone Mainardi <[email protected]> wrote:
> Hi to all and thanks in advance for any help!
> I'm trying to set up a DB with a many-to-many relation containing an
> attribute in the 'secondary' table. Let me post some code to be more
> clear
>
> //begin code
> sottoconti_ce_proporzionali_ce_per_attivita = Table
> ('sottoconti_ce_proporzionali_ce_per_attivita', metadata,
> Column('sottoconto_id', Integer, ForeignKey('sottoconto_ce.id',
> onupdate="CASCADE", ondelete="CASCADE"), primary_key=True),
> Column('attivita_id', Integer, ForeignKey('attivita.id',
> onupdate="CASCADE", ondelete="CASCADE"), primary_key=True),
> Column('sottoconto_proporzionale_id', Integer, ForeignKey
> ('sottoconto_ce.id', onupdate="CASCADE", ondelete="CASCADE"))
> )
>
> class SottocontoCE(DeclarativeBase):
> __tablename__ = 'sottoconto_ce'
>
> id = Column(Integer, primary_key=True)
> nome = Column(Unicode(255), unique=True, nullable=False)
> descrizione = Column(Unicode(255))
>
> class Attivita(DeclarativeBase):
> __tablename__ = 'attivita'
>
> id = Column(Integer, primary_key=True)
> nome = Column(Unicode(255), unique=True, nullable=False)
> descrizione = Column(Unicode(255))
>
> sottoconti_ce_proporzionali_ce = relation('SottocontoCE',
> secondary=sottoconti_ce_proporzionali_ce_per_attivita,
>
> primaryjoin=id==sottoconti_ce_proporzionali_ce_per_attivita.c.attivita_id,
>
> secondaryjoin=sottoconti_ce_proporzionali_ce_per_attivita.c.sottoconto_id==
> SottocontoCE.id,
> foreign_keys=
> [sottoconti_ce_proporzionali_ce_per_attivita.c.attivita_id,
>
> sottoconti_ce_proporzionali_ce_per_attivita.c.sottoconto_id])
>
> class SottocontiCEProporzionaliCEPerAttivita(DeclarativeBase):
> __table__ = sottoconti_ce_proporzionali_ce_per_attivita
> sottoconto=relation('SottocontoCE',
>
> primaryjoin=sottoconti_ce_proporzionali_ce_per_attivita.c.sottoconto_id==So
> ttocontoCE.id,
> foreign_keys=
> [sottoconti_ce_proporzionali_ce_per_attivita.c.sottoconto_id])
> attivita=relation('Attivita')
> sottoconto_proporzionale=relation('SottocontoCE',
> primaryjoin=sottoconti_ce_proporzionali_ce_per_attivita.c.sottoconto_propor
> zionale_id==SottocontoCE.id,
> foreign_keys=
> [sottoconti_ce_proporzionali_ce_per_attivita.c.sottoconto_proporzionale_id] )
>
> def __init__(self, sottoconto=None, attivita=None,
> sottoconto_proporzionale=None):
> self.sottoconto=sottoconto
> self.attivita=attivita
> self.sottoconto_proporzionale=sottoconto_proporzionale
> //end code
>
> the class SottocontiCEProporzionaliCEPerAttivita is used as a mapping
> for the table sottoconti_ce_proporzionali_ce_per_attivita.
> the columns sottoconto_proporzionale_id and sottoconto_id are both
> foreign keys to class SottocontoCE.
> Now suppose sc1 and sc2 are instances of SottocontoCE and att of
> Attivita. If I want to create an association such that att owns sc1
> which is related to sc2:
> assoc = SottocontiCEPRoporzionaliCEPerAttivita(sc1, att, sc2)
> everything is fine and when i commit canges a new entry in the table
> sottoconti_ce_proporzionali_ce_per_attivita is pushed in the DB
> But, if I call
> att.sottoconti_ce_proporzionali_ce I get the following from the
> interpreter
>
> >>> att.sottoconti_ce_proporzionali_ce
>
> 14:27:07,890 INFO [sqlalchemy.engine.base.Engine.0x...5d90] SELECT
> sottoconto_ce.id AS sottoconto_ce_id, sottoconto_ce.nome AS
> sottoconto_ce_nome, sottoconto_ce.descrizione AS
> sottoconto_ce_descrizione, sottoconto_ce.conto_id AS
> sottoconto_ce_conto_id
> FROM sottoconto_ce, sottoconti_ce_proporzionali_ce_per_attivita
> WHERE ? = sottoconti_ce_proporzionali_ce_per_attivita.attivita_id AND
> sottoconti_ce_proporzionali_ce_per_attivita.sottoconto_id =
> sottoconto_ce.id
> 14:27:07,890 INFO [sqlalchemy.engine.base.Engine.0x...5d90] [1]
> []
>
>
>
> why this is an empty list? I should see sc1...
> Thanks again for any help and sorry for the italian names of the
> attributes, but they are economical technicalities ^_^
>
> Simone
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---