On 05/03/2016 06:28 PM, Tim-Christian Mundt wrote:
I have entities which I’d like to tag with tags from a vocabulary. The 
associations between entities and tags are implemented with „manual M:N“, 
because they carry more information.

class Entity(Base):
     id = Column(Integer, primary_key=True)
     tags = relationship('TagAssociation', backref='entity',
                         cascade="all, delete, delete-orphan")

class Vocabulary(Base):
     id = Column(Integer, primary_key=True)
     name = Column(String(255), nullable=False, unique=True)

class Tag(Base):
     id = Column(Integer, primary_key=True)
     vocabularyId = Column(Integer, ForeignKey(Vocabulary.id), nullable=False)
     vocabulary = relationship(Vocabulary, lazy='joined',
                               backref=backref('tags', cascade='all, 
delete-orphan'))
     name = Column(String(50), nullable=False)

class TagAssociation(Base):
     entityId = Column(Integer, ForeignKey(Entity.id), primary_key=True)
     tagId = Column(Integer, ForeignKey(Tag.id), primary_key=True)
     tag = relationship(Tag, lazy='joined‘)


Now I want to make sure that I don’t have more than one tag from a single 
vocabulary on an entity. Currently I’m using
the before_insert event on TagAssociation which works well except in this case:

entity = Entity()
entity.tags.append(TagAssociation(entity=entity, tag=some_tag))
session.add(entity)
session.flush()
entity.tags = [TagAssociation(entity=entity, 
tag=some_other_tag_from_same_vocabulary)]
session.flush()

When the validation function is called during the second flush, the collection 
(assoc_to_be_inserted.entity.tags)
has both tags in it (which I don’t understand).

This is not enough detail for me to reproduce that, you'd need to show me how to illustrate the .tags collection storing two TagAssociation objects when you've explicitly set the collection to store a single TagAssociation. That's not anything that reproduces here.



I couldn’t find a way to detect if one of them is going to be deleted.

if a collection is assigned to a specific value, then the items that are no longer present in that collection are added to a list called "deleted". That can be seen like this:

from sqlalchemy import inspect

inspect(my_entity).attrs.tags.history


Hence, the validation fails, although the final result would be correct.

Is there any event I can use to reliably implement that validation?

There's not enough detail here for me to know exactly how you're doing this validation and under what scenario you're seeing something unexpected. The best format is to send an MCVE (http://stackoverflow.com/help/mcve).







Thanks,
Tim


--
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to