[sqlalchemy] Re: How does query.get() work?
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
[sqlalchemy] Re: How does query.get() work?
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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: How does query.get() work?
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 -~--~~~~--~~--~--~---
[sqlalchemy] Re: How does query.get() work?
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 -~--~~~~--~~--~--~---