On 10/14/2010 01:30 PM, Chris Withers wrote: > Hi All, > > I currently have code that looks like this: > > recipients = [] > if recipient_ids: > for id in recipient_ids.split(','): > recipients.append( > session.query(recipient.Recipient).filter_by(id=id).one() > ) > else: > recipient_ids = () > feed.recipients = recipients > > Where the models are: > > feed_recipient = Table('feed_recipient', Base.metadata, > Column('feed_id', String(length=32), ForeignKey('feed.id')), > Column('recipient_id', Integer, ForeignKey('recipient.id')), > ) > > class Feed(Base): > __tablename__ = 'feed' > id = Column(String(length=32), primary_key=True) > recipients = relation('Recipient', secondary=feed_recipient) > > class Recipient(Base,ComputedMapperArgs): > __tablename__='recipient' > feeds = relation('Feed', secondary=feed_recipient) > > It feels like a horribly inefficient way of updating the many-to-many > relationship. I guess I could just use the sql abstraction layer, but > that feels like circumventing the ORM without just cause ;-) > > Am I missing something? If I have a sequence of ids where I want to > update the many to many relationship as above, what's the best way of > doing it?
You can at least reduce it to a single query: recipient_id_list = recipient_ids.split(',') q = session.query(recipient.Recipient) q = q.filter(recipient.Recipient.id.in_(recipient_id_list)) recipients = q.all() if len(recipients) != len(recipient_id_list): invalid_ids = (set(recipient_id_list) - set(x.id for x in recipients)) raise StandardError("Invalid recipient ids: %s" % sorted(invalid_ids)) feed.recipients = recipients I wish there was an easy way to do, say: feed.recipients.ids = recipient_id_list which would let you avoid querying at all. The downside is you won't notice invalid ids until the next flush(). Alternatively, you could also accomplish this via: feed.recipients = [session.merge(recipient.Recipient(id=id), load=False) for id in recipient_id_list] if session.merge() allowed you to merge newly-created transient objects with load=False. Maybe add a "force" parameter to merge, to tell SQLAlchemy that you really know what you are doing? -Conor -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalch...@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.