Oh! Okay, I think I get you now. The only reason I pass a list of table objects is that I need the name, and I thought I needed the table to query. If I can obtain the table name from the class (.__tablename__), then this should work, with no need to mess with table objects at all. I'll try it. Thanks for the help!
On 2/4/16, Simon King <si...@simonking.org.uk> wrote: > You need to use the class when querying the database. SQLAlchemy will then > return an instance of that class for each matching row: > > customer = session.query(Customer).filter_by(name=u'Powersports > Etc').first() > customer.name = u'New Name' > session.flush() > > The getAllClasses function I showed was meant to be a direct analog to your > getAllTables function, which was returning the tables themselves. You were > then passing those to session.query() to get a whole load of rows back, but > those rows were not update-able. I was trying to suggest that if you > replaced those Table objects with mapped classes (such as Customer), then > when those classes were passed to session.query(), what you get back will > be Customer *instances*. > > session.query(someTable) returns glorified tuples that can't be updated > session.query(someMappedClass) returns instances of someMappedClass, that > *can* be updated. > > Hope that makes sense, > > Simon > > On Thu, Feb 4, 2016 at 2:07 PM, Alex Hall <ah...@autodist.com> wrote: > >> This is where sqlalchemy gets murky for me. If I return all classes, >> I'm not returning all *instances* of those classes. How, then, would I >> update a given customer's record? The objects (c1 and c2, for >> instance) were instantiated elsewhere, and my GUIManager module has no >> knowledge of them. More generally, when I switch this over to our >> AS400 and start querying, I won't have created any records at all. >> Every record will be pulled from a table on the 400, and while I will >> have a schema, I won't have any instances of that schema. >> >> As I think about this, it occurs to me that I should *create* the >> record objects from the records. That is: >> >> for record in recordsList: #an array of session.query(someTable).all() >> myTempRecord = mySchemaClass(record) >> myTempRecord.property = newValue >> #update the database >> >> Assuming GUIManager knows about mySchemaClass, would that approach >> work? How I'd pass in a record and get back an instance of >> mySchemaClass I'm not yet sure, but is this worth looking into more, >> or am I on the wrong track? >> >> On 2/4/16, Simon King <si...@simonking.org.uk> wrote: >> > getAllTables is returning Core Table objects. I suppose you could have >> > a >> > similar function which returns all mapped classes, something like this: >> > >> > def getAllClasses(): >> > return base.__subclasses__() >> > >> > (If your class hierarchy is more complicated you'd need a more >> > sophisticated function there) >> > >> > Simon >> > >> > On Thu, Feb 4, 2016 at 12:32 PM, Alex Hall <ah...@autodist.com> wrote: >> > >> >> Yes, I'm using Declarative. I was following a great tutorial, then >> >> realized it was way out of date. The one recommended on the forum I >> >> found said to use Declarative, so I did. >> >> >> >> In DBInterface, I have this little function: >> >> >> >> def getAllTables(): >> >> return base.metadata.tables >> >> #end def getAllTables >> >> >> >> I then loop over that array, grabbing the value only and ignoring the >> >> key. I just tried printing the type, as in: >> >> >> >> def getAllTables(): >> >> for table in base.metadata.tables.values(): >> >> print type(table) >> >> return base.metadata.tables >> >> #end def getAllTables >> >> >> >> I got <class 'sqlalchemy.sql.schema.Table'> Here's the loop that >> >> generates the table list passed to my GUI (remember that this must be >> >> an array of arrays): >> >> >> >> tables = DBInterface.getAllTables() >> >> tablesList = [] >> >> for table in tables.values(): >> >> tablesList.append([table]) >> >> #end for >> >> >> >> Just to be sure, I stuck a "print type(table)" statement in that for >> >> loop, and the objects are still sqlalchemy.sql.schema.Table objects. >> >> >> >> On 2/4/16, Simon King <si...@simonking.org.uk> wrote: >> >> > SQLAlchemy has 2 main layers, the "Core" layer which deals with >> >> > mostly >> >> > database-level constructs, such as Tables, and the ORM layer, which >> >> > is >> >> > built on top of Core. With the ORM, you map your own classes onto >> >> > the >> >> > lower-level Tables, then work with instances of those classes. You >> >> > appear >> >> > to be using the declarative system to define your classes, so >> >> > SQLAlchemy >> >> > will be creating the associated Table instances for you under the >> hood. >> >> > >> >> > In your example, Customer is an ORM-level class. Somewhere, there >> >> > will >> >> be a >> >> > construct representing the Core-level Table that the Customer class >> >> > is >> >> > mapped to. (It's probably available at Customer.__table__, but also >> >> > in >> >> > other places). >> >> > >> >> > When you say that "self.choices" contains table objects, I suspect >> that >> >> > those are the Core-level Table instances. When you query using >> >> > those, >> >> > you >> >> > don't get Customer objects back. You need to query using the >> >> > Customer >> >> class >> >> > instead. Can you get the Customer class into your self.choices >> >> > array, >> >> > either instead of the table, or as well as? Where are you getting >> >> > the >> >> > object that you are putting in the first element of each of the >> >> > self.choices list? >> >> > >> >> > Simon >> >> > >> >> > On Thu, Feb 4, 2016 at 11:34 AM, Alex Hall <ah...@autodist.com> >> wrote: >> >> > >> >> >> It's all from a GUI, so it's something like this (my code isn't in >> >> >> front >> >> >> of me): >> >> >> DBInterface.session"query(self.choices[self.selectedIndex][0]).all() >> >> >> Choices is a 2D array where the first (0th) element of each >> >> >> sub-array >> >> >> is >> >> >> a >> >> >> table object. The query works, because I get the records as >> >> >> expected >> >> >> and >> >> >> can display them or inspect them. I just can't modify them for some >> >> >> reason. >> >> >> As I said, though, I'm new to this package so am likely missing an >> >> >> obvious >> >> >> step, or have something set up very wrong. >> >> >> >> >> >> Sent from my iPhone >> >> >> >> >> >> > On Feb 3, 2016, at 16:18, Simon King <si...@simonking.org.uk> >> wrote: >> >> >> > >> >> >> > OK, so you’re not actually getting Customer objects back from >> >> >> > your >> >> >> query. What does your call to session.query() look like? For this >> >> >> to >> >> >> work, >> >> >> it really ought to be something like “session.query(Customer)”. I >> >> suspect >> >> >> you are doing something like “session.query(Customer.id, >> >> >> Customer.name, >> >> >> …)” >> >> >> instead. >> >> >> > >> >> >> > Simon >> >> >> > >> >> >> >> On 3 Feb 2016, at 17:43, Alex Hall <ah...@autodist.com> wrote: >> >> >> >> >> >> >> >> I'm on the Gmail site, so am not sure I can reply in-line. >> >> >> >> Sorry. >> >> >> >> >> >> >> >> This is a basic table class, like >> >> >> >> class Customer(base): >> >> >> >> __tablename__ = "customers" >> >> >> >> name = Column(String(50)), >> >> >> >> ... >> >> >> >> >> >> >> >> When I print the type: >> >> >> >> <class 'sqlalchemy.util._collections.result'> >> >> >> >> And repr(): >> >> >> >> (2, u'Powersports Etc', 5554443210L, >> >> >> >> u'ahall+dbte...@autodist.com >> ', >> >> >> True) >> >> >> >> >> >> >> >> >> >> >> >>> On 2/3/16, Simon King <si...@simonking.org.uk> wrote: >> >> >> >>>> On Wed, Feb 3, 2016 at 3:54 PM, Alex Hall <ah...@autodist.com> >> >> >> >>>> wrote: >> >> >> >>>> >> >> >> >>>> Hello list, >> >> >> >>>> I'm new to SQLAlchemy, but not to Python. I have an >> >> >> >>>> application >> >> >> >>>> that's >> >> >> >>>> coming together, and relies on SQLAlchemy to talk to a >> >> >> >>>> database >> >> >> >>>> for >> >> >> >>>> many of the app's functions. Listing tables, listing records, >> >> >> >>>> updating >> >> >> >>>> records, pulling records for internal use, and so on. >> >> >> >>>> >> >> >> >>>> My app is working, but so far I've been writing the framework >> and >> >> >> >>>> GUI >> >> >> >>>> with a bit of SQLite just to check that things are working how >> >> >> >>>> I >> >> >> >>>> want. >> >> >> >>>> Now, though, I'm getting into my first "real" user-facing >> >> >> >>>> database >> >> >> >>>> task: taking the values from a dialog and updating a record >> >> >> >>>> according >> >> >> >>>> to those values. Thus far, I'm having no luck. >> >> >> >>>> >> >> >> >>>> My organization for now is DBInterface.py, which holds all my >> >> >> >>>> table >> >> >> >>>> definitions, database details, and my base, session, and >> >> >> >>>> engine >> >> >> >>>> objects. I can hear the groans from here; I do plan to move >> >> >> >>>> the >> >> >> >>>> table >> >> >> >>>> definitions into a module of their own at some point, there >> >> >> >>>> simply >> >> >> >>>> hasn't been a need yet. GUIManager.py imports DBInterface, and >> >> >> >>>> handles >> >> >> >>>> all the GUI stuff, as the name suggests. It's where, >> >> >> >>>> eventually, >> >> >> >>>> I'll >> >> >> >>>> take user input and use it to update records by calling >> functions >> >> >> >>>> from >> >> >> >>>> DBInterface. That's the problem, though. In GUIManager, I have >> >> >> >>>> a >> >> >> >>>> simple test: >> >> >> >>>> >> >> >> >>>> self.records[self.selectedRecordIndex].name="test name" >> >> >> >>>> #records >> >> >> >>>> is >> >> >> >>>> the list of objects returned by querying the current table >> >> >> >>>> >> >> >> >>>> Which errors out every time: >> >> >> >>>> AttributeError: can't set attribute >> >> >> >>>> >> >> >> >>>> (Yes, "name" is an attribute name of my Customer class.) From >> >> >> >>>> what >> >> >> >>>> I've read thus far, updating records is as easy as modifying >> >> >> >>>> their >> >> >> >>>> properties and calling session.commit(). That isn't working, >> >> though. >> >> >> >>>> I >> >> >> >>>> imagine the problem is that the records in a query aren't the >> >> >> >>>> same >> >> >> >>>> as >> >> >> >>>> the records originally created, and modify/commit only works >> >> >> >>>> on >> >> >> >>>> those >> >> >> >>>> originals. I'm not sure if that's right, though. If it is, how >> >> could >> >> >> >>>> I >> >> >> >>>> modify the originals, given that I run a new query each time >> >> >> >>>> the >> >> >> >>>> user >> >> >> >>>> selects a table name in my GUI's list of names? If I'm wrong, >> how >> >> >> >>>> would I update the record attributes and save the changes back >> to >> >> >> >>>> the >> >> >> >>>> database? I think I'm picturing this whole thing wrong, to be >> >> >> >>>> honest. >> >> >> >>>> Thanks for any help, and please let me know if I need to >> >> >> >>>> provide >> >> >> >>>> more >> >> >> >>>> code or context. >> >> >> >>> Is your query against a single mapped class, or is it against >> some >> >> >> >>> set >> >> >> of >> >> >> >>> columns? What do you get if you write: >> >> >> >>> >> >> >> >>> print type(self.records[self.selectedRecordIndex]) >> >> >> >>> print repr(self.records[self.selectedRecordIndex]) >> >> >> >>> >> >> >> >>> ...at the point where you are trying to set the name? >> >> >> >>> >> >> >> >>> 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. >> >> >> >> >> >> >> >> -- >> >> >> >> 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. >> >> >> > >> >> >> > -- >> >> >> > 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. >> >> >> >> >> >> -- >> >> >> 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. >> >> >> >> >> > >> >> > -- >> >> > 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. >> >> > >> >> >> >> -- >> >> 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. >> >> >> > >> > -- >> > 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. >> > >> >> -- >> 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. >> > > -- > 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. > -- 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.