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
-~----------~----~----~----~------~----~------~--~---

Reply via email to