What I would do is simply iterate through the list of id's the user
gives.  Then use sess.query(SomeClass).get(id)  to retrieve the
required instance, apply changes if needed and loop to the next id.

Then issue sess.commit()  at the end.

SA will take care of either updating things from the db, or simply
using the entities its already retrieved previously.

The important thing to take care of is how you manage the session.  If
you already closed the session you used previously to retrieve the
entities their state will be lost, and 'get' on a new session will
definately issue sql to retrieve it from the db.  So if you keep
everything within one session there will be a smaller chance that SA
will actually issue sql, though it depends on whether the instance
states have been expired or not.

If you really just need a cache for instances SA's probably not the
way to go though.


2009/3/31 Dan F <danielfal...@gmail.com>:
>
> It's not so much that I'm querying but that I get a set of id's from the
> user and I've got some logic that will often change some of the values.
> I wanted to take advantage of SA's orm capabilities as opposed to
> issuing selects and updates.  It's possible in the logic that I already
> have some of the entities retrieved, but it didn't make sense for me to
> pass around a map, knowing that SA already keeps one.  And that still
> doesn't seem quite right--having to manage which objects I've previously
> selected.  Perhaps I should just issue the updates.
>
>
> Christiaan Putter wrote:
>> Hi,
>>
>> Small extract from the query's _get method:
>>
>>         if not self._populate_existing and not refresh_state and not
>> self._mapper_zero().always_refresh and lockmode is None:
>>             try:
>>                 instance = self.session.identity_map[key]
>>                 state = attributes.instance_state(instance)
>>                 if state.expired:
>>                     try:
>>                         state()
>>                     except orm_exc.ObjectDeletedError:
>>                         self.session._remove_newly_deleted(state)
>>                         return None
>>                 return instance
>>             except KeyError:
>>                 pass
>>
>>
>> So you have access to the identity map through
>> session.identity_map[key], where key is:
>>
>> key = self._only_mapper_zero("get() can only be used against a single
>> mapped class.").identity_key_from_primary_key(ident)
>>
>> ident is the primary key for the record you're looking for.
>>
>> The above will basically return the instance to you if it's already in
>> the identity map.  Though state() will still execute sql to refresh
>> attributes.
>>
>> So what you can do is build a loop using something like that going
>> through all the primary keys you'd like to get directly from the
>> identity mapper.  I'm assuming it's using a pretty good hash so access
>> should be some constant factor.  Then you can use the normal
>> query.get() to retrieve the ones that failed from the database.
>>
>>
>> This is really something I would advise against though.
>>
>> What exactly are you querying for?  Why don't you just keep a list of
>> all the instances you've already loaded?
>>
>>
>>
>>
>>
>> 2009/3/25 Dan F <danielfal...@gmail.com>:
>>
>>> I understand what get() is supposed to do, but it doesn't clear it up
>>> because it still seems like there should be a way of retrieving a
>>> *set* of records back from the database at once.  I only see a couple
>>> choices currently.  Either I can use filter() and retrieve every
>>> record in the set (even the ones that are mapped), or I can use get on
>>> each row individually.  Since get() checks the identity map, it won't
>>> get records it doesn't need to get, but on the other hand, each record
>>> has to get retrieved in its own call.
>>>
>>> Does this make sense, and do I have it right?
>>>
>>> Thanks.
>>>
>>>
>>> On Mar 24, 2:08 am, Christiaan Putter <ceput...@googlemail.com> wrote:
>>>
>>>> Hi,
>>>>
>>>> You won't be able to get() multiple objects at the same time.
>>>> query(SomeClass).get(pk1, pk2, pk3)  takes in a tuple of values
>>>> representing the primary key of some record in your table.  In this
>>>> case the primary key consists of three separate columns (thus a
>>>> composite key), though the record they identify will always be unique
>>>> within your table.  That's sort of the point of it being a primary
>>>> key.  Read the docs for an explanation of what parameters get()
>>>> expects.
>>>>
>>>> Of course you could use filter() and get the same result.  I'm not
>>>> sure but I guess the actual SQL executed by SA should look exactly the
>>>> same, set echo to True and have a look.
>>>>
>>>> The difference being of course that you can use filter to return more
>>>> then one record.
>>>>
>>>> I'm not sure how get() works on databases that don't need primary
>>>> keys.  I'm guessing it won't.  Maybe it's in the docs.
>>>>
>>>> Hope that cleared things up.
>>>>
>>>> Regards,
>>>> Christian
>>>>
>>>> 2009/3/23 Dan F <danielfal...@gmail.com>:
>>>>
>>>>
>>>>
>>>>
>>>>> Hi,
>>>>>
>>>>> Is there a difference between using query.get(ident) and using
>>>>> query.filter(MyClass.id.in_())?  Specifically with regard to how the
>>>>> mapper is used?  If I'm right in my assumption, get() uses the map to
>>>>> avoid extra lookups, but I question whether the filter method is doing
>>>>> the same.  If I'm correct, shouldn't there be a way to get() multiple
>>>>> objects at the same time?
>>>>>
>>>>> Thanks.
>>>>>
>>
>> >
>>
>
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@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
-~----------~----~----~----~------~----~------~--~---

Reply via email to