On Wed, Mar 16, 2016 at 1:07 PM, Alex Hall <ah...@autodist.com> wrote:
> Hello all, > I'm running a different query than yesterday. Before, I had something like: > > items = session.query(itemTable, attachmentTable, attachmentTextTable, > assignmentTable, attributeTable, attributeValueTable, > attributeValueAssignmentTable, vendorTable)\ > .filter(attachmentTable.itm_id == itemTable.itm_id)\ > #and so on, a bunch of .filter calls > > Then, in the loop iterating over the results, I could do this: > > for result in queryResults: > itemID = result.item.itm_id > Because you wrote "session.query(itemTable, attachmentTable, attachmentTextTable)", the results that you get back from the query are like a tuple with 3 items corresponding to the 3 tables that you queries. result[0] would be the data from itemTable, result[1] is from attachmentTable, and result[2] is from attachmentTextTable. It also supports name-based access, which is why you were able to refer to "result.item" and "result.attach_text". > > Now that I'm using a bunch of outer left joins, that code is suddenly > not working. I get an error when I say > result.item.itm_id > AttributeError: 'item' object has no attribute 'item' > > The problem is that my query starts out with only one table passed to > session.query(), not all of them. Thus my result is of type 'item', > which is the table passed in. That would be okay, except that I need > to access values of other tables in the result, so even if I change > id = result.item.itm_id > to > id = result.itm_id > When I then say > description = result.attach_text.att_value > AttributeError: 'item' object has no attribute 'attach_text' > > First, it helps to be precise about your terminology. SQLAlchemy distinguishes between the object representing a table, and a class that you are mapping to that table. You've talked about using automapper in the past, so I assume you are passing a mapped class, not a table, to session.query(). When you pass a single mapped class, the results you get back are instances of that class. > I know why it doesn't. What I don't know is how to get my query > results to hold all the information from all the tables, or how to > access it if they do already, but in a different way than before. My > new query is this: > > items = session.query(itemTable)\ > .outerjoin(vendorTable, vendorTable.PVVNNO == itemTable.itm_vendornum)\ > .outerjoin(assignmentTable, assignmentTable.itm_id == itemTable.itm_id)\ > .filter(assignmentTable.att_id == attachmentTable.att_id)\ > .outerjoin(attachmentTextTable, assignmentTable.att_id == > attachmentTextTable.att_id)\ > .outerjoin(attributeValueAssignmentTable, > attributeValueAssignmentTable.itm_id == itemTable.itm_id)\ > .outerjoin(attributeTable, attributeTable.attr_id == > attributeValueAssignmentTable.attr_id)\ > .filter(attributeValueTable.attr_value_id == > attributeValueAssignmentTable.attr_value_id)\ > .yield_per(1000) > > I've also tried the same query, but with the first line changed to: > items = session.query(itemTable, attachmentTable, attachmentTextTable, > assignmentTable, attributeTable, attributeValueTable, > attributeValueAssignmentTable, vendorTable)\ > > The problem here is that, while result.item.* works as expected, other > tables don't. For instance, result.attach_text.att_value yields an > AttributeError, 'None' type object has no attribute att_value. > Clearly, the other tables are in the result, but they're all None. I > expected something like that, and only added them back in to see if it > might help, but since I call query().outerjoin() I didn't think it > would work. > > I should note that I renamed most of the tables by assigning variables > to base.classes.tableName, which is why I'm using "itemTable" here, > but in getting attributes of results I use just "item". The 'item' > table is called 'item', but I assigned it to a variable called > 'itemTable', just for clarity in the script. > > Is there a way to access the values of a query like this? At the very > least, is there a way I can print out all the objects the result > object has, so I can work out what to do? Thanks for any help! > > Normally you would do this by setting up relationships between your mapped classes, so that when you access "item.attach_text", SQLAlchemy will go and fetch the related object: http://docs.sqlalchemy.org/en/rel_1_0/orm/tutorial.html#building-a-relationship Once you've got the relationship in place, you can set options on the query to control whether to load the related objects immediately, or to wait until they are accessed: http://docs.sqlalchemy.org/en/rel_1_0/orm/tutorial.html#eager-loading Automap may have already set up relationships between your classes. The way it does this is described here: http://docs.sqlalchemy.org/en/rel_1_0/orm/extensions/automap.html#relationship-detection Hope that helps, Simon -- 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 sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.