class SageProxy(object):
@classmethod
def ismapped(cls, table_name=None):
if mappings:
if table_name:
if mappings.has_key(table_name):
tmap=mappings[table_name]
if tmap.has_key('class'):
tclass=tmap['class']
if tclass is cls:
return True
else:
for m in mappings:
if cls is m['class']:
return True
return False
@classmethod
def mappingprops(cls):
#override this to pass properties to sqlalchemy mapper function
return None
@classmethod
def columns_descriptors(cls):
#override this to map columns to different class properties names
#return dictionary where key is the column name and value is the desired property name
return {}
@classmethod
def mapTo(cls, table_name, map_opts=None):
if not cls.ismapped(table_name):
tab_obj=Table(table_name,sage_md,autoload=True)
for c in tab_obj.c:
#clean field names
tab_obj.c[c.name].key=c.key.replace(u'%',u'Porcentaje').replace(u'ñ',u'ny').replace(u'Ñ',u'NY').replace(u'-',u'_')
for k,v in cls.columns_descriptors():
if tab_obj.c[k]:
tab_obj.c[k].key=v
mapper(cls, tab_obj, properties=cls.mappingprops())
mappings[table_name]={'table':tab_obj,'class':cls}
return cls
#-*- coding:utf-8 -*-
import sqlalchemy as sa
import sqlalchemy.orm
engine = sa.create_engine('sqlite://', echo=True) # new memory-only database
metadata = sa.MetaData(bind=engine)
# create a table. This could be reflected from the database instead:
tb = sa.Table('foo', metadata,
sa.Column(u'id', sa.Integer, primary_key=True),
sa.Column(u'nomé', sa.Unicode(100)),
sa.Column(u'ãéìöû', sa.Unicode(100))
)
tb.create()
class Foo(object):
pass
# maps the table to the class, defining different property names
# for some columns:
sa.orm.mapper(Foo, tb, properties={
'nome': tb.c[u'nomé'],
'aeiou': tb.c[u'ãéìöû']
})
metadata = MetaData(bind=engine, reflect=True)
sm = sessionmaker(bind=engine)
class tblOrders(Base):
__table__ = metadata.tables['tblOrders']
meter = __table__.c['Meter#']
我也遇到了同样的问题,最后成功地替换了table['column'].key。在自动加载它之后,只需让所有表类都继承这个表,然后在mapTo方法中修改列名替换,或者用dictionary和columns_描述符方法手动覆盖所需的名称。我不知道这是否是正确的方法,但经过数小时的搜索是我所能找到的最好的方法。在
我希望它会有用
将表映射到类将在类上创建映射属性。默认情况下,属性与列的名称相同。由于python2.x只允许使用ascii标识符,因此如果您有非ascii列名,那么这将失败。在
我能想到的唯一解决方案是在将表映射到类时给标识符一个不同的名称。在
下面的例子就是这样。请注意,为了简单起见,我在代码上创建表,因此任何人都可以在没有现有表的情况下运行代码。但是你可以用反射表来做同样的事情。在
之后,您可以使用
Foo.nome
来引用nomé
列,Foo.aeiou
来引用ãéìöû
列。在我发现只要在反射类中添加一个简单的元素就可以做到这一点:
^{pr2}$meter
现在映射到底层的Meter#
列,该列允许以下代码工作:如果没有映射,python将其视为一个断开的语句,因为对象中不存在
Meter
后跟注释。在相关问题 更多 >
编程相关推荐