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
<[email protected]> 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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---