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 [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.