Hi Tomasz, Thanks, but I think that your suggestion gives me the attributes within the class, and this is not what I need. The problem is that if I have a None value where there could also be an Integer (nullable FK for instance), then take the type from a mapper prop I am going to end up with None type when what I really want is an Integer type. I think the only way to be sure of the type is to pull it directly from the table column definitions and not look at teh values within the class.
Below, I have code to do that. It's not pretty but it passes through the inheritance chain and places all the table columns into the cols {}. I do end up touching the PK, which is a no-no and I am pretty sure there are some edge cases that I am missing. Still, I have a problem when I try to cast the value. How to I convert a SA type to a Python type so that I can cast it to my Python class attributes? field_type = cols[k].type # This gives me SA types (Integer(), Unicode(length=20), etc) NOT Python types setattr(self, k, field_type(v)) # Won't work. field_type doesn't cast to Python. Getting there, but still messy. - Shane # Need to check types within the database and make v the correct value. def saveAttrs(self, kw): print '================= in [saveAttrs] with kw =' + str(kw) + '====================' # Load current class's DB table, then check if you are at the cols = {} table = metadata.tables[self.__tablename__] # Place self's table columns into cols. for col in table.c: cols[col.name] = col # Now go through the inheritance tree and put base class columns into cols. Only add to cols # when you don't see a __tablename__, since this is either DeclarativeBase or another # inherited class w/o mapping for base in self.__class__.__bases__: if hasattr(base, '__tablename__'): # Got to be a better way to do that... table = metadata.tables[base.__tablename__] for col in table.c: cols[col.name] = col # Check my work. Make sure all kw values go into the right place for k,v in kw.iteritems(): print 'Running with key = ' + k if hasattr(self, k): if k in cols: field_type = cols[k].type print 'Key = ' + str(k) + ', Val= ' + str(v) + ' ColType = ' + str (field_type) # DIES HERE. Can't just cast a SQ type ============> setattr(self, k, field_type(v)) On Oct 30, 7:34 am, Tefnet Developers - Tomasz Jezierski <develop...@tefnet.pl> wrote: > Dnia 2009-10-30, Pt o godzinie 01:44 -0700, Shane pisze: > > > > > Hi All, > > > I am using SA within TurboGears. When saving data from form fields, I > > often have a dict of key/value pairs (where values is always a string > > and must by correctly typed) where each key is set up to correspond to > > a column within the SA Table: > > (Data from fields for a ProductLineItem Type) > > kw = {'bol': u'', 'gross_qty': u'', 'id': u'-1', 'item': u'4', > > 'net_qty': u'', 'order_id': u'2', 'ordered_qty': u'8800', 'supplier': > > u'2', 'terminal': u'8'} > > > I have been manually using setter methods to type-define and save each > > dict value with the correct variable within my LineItem class, but > > this is getting fairly tedious. I wanted a way to just save my entire > > dict using a method within LineItems like: > > > ====================== > > class LineItem(DeclarativeBase): > > > __tablename__ = 'line_item' > > __table_args__ = {'mysql_engine':mysql_engine_type} > > id = Column(Integer, primary_key=True) > > order_id = Column(Integer, ForeignKey('order.id')) > > ordered_qty = Column(Integer) > > net_qty = Column(Integer) > > item_id = Column(Integer, ForeignKey('item.id')) > > class_type = Column('class_type', String(50)) > > __mapper_args__ = {'polymorphic_on':class_type} > > > .... > > def saveTG(self, kw): > > # Load current classes DB table. > > table = metadata.tables[self.__tablename__] > > for k,v in kw.iteritems(): > > if k in dir(self): > > # Get the type of the SA column since > > the value in the class may be a None or > > # undefined. > > field_type = type(table.c[k]) > > setattr(self, k, field_type(v)) > > ... > > > ====================== > > class ProductLineItem(LineItem): > > TYPE = 'product' > > GROSS = 'gross_qty' > > BOL = 'bol' > > TERMINAL = 'terminal_id' > > SUPPLIER = 'supplier_account_id' > > > __tablename__ = 'product_line_item' > > __table_args__ = {'mysql_engine':mysql_engine_type} > > id = Column(Integer, ForeignKey('line_item.id'), primary_key = True) > > gross_qty = Column(Integer) > > bol = Column(Unicode(20), nullable=True) > > terminal_id = Column(Integer, ForeignKey('terminal.id'), nullable = > > True) > > supplier_account_id = Column(Integer, ForeignKey > > ('terminal_supplier_account.id'), nullable = True) > > __mapper_args__ = {'polymorphic_identity': 'product'} > > > Ex: > > line = LineItem() > > line.saveTG(kw) > > > This works since I am working on the base class, but if I use a > > ProductLineItem > > > line=ProductLineItem() > > line.saveTG(kw) > > > If fails since my table contains only the columns for > > ProductLineItem. So how can I get all the columns that a > > ProductLineItem works with? I think i am making this too hard and > > that it is something that should be easy to do. > > > I appreciate any suggestions! > > Hi > I think you want mapper properties not table columns? > > sqlalchemy.orm.mapper.Mapper.iterate_properties ? > > http://www.sqlalchemy.org/docs/05/reference/orm/mapping.html?highligh... > > for prop in sqlalchemy.orm.class_mapper( something ).iterate_properties: > print prop.key > > Tomasz Jezierski > Tefnetwww.tefnet.pl --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---