SQLAlchemy对声明式类的内省

7
我正在编写一个小的SQLAlchemy包装器,用于从MySQL数据库导出数据并进行一些轻量级数据转换,主要是更改字段名称。我的当前脚本运行良好,但需要我基本上两次描述我的模型——一次在类声明中,一次作为要迭代的字段名称列表。
我正在尝试找出如何使用内省来识别行对象上的列访问器属性。以下代码几乎完美地解决了这个问题:
for attr, value in self.__class__.__dict__.iteritems():
    if isinstance(value, sqlalchemy.orm.attributes.InstrumentedAttribute):
        self.__class__._columns.append(attr)

除了我的“一对多关系访问器”也是sqlalchemy.orm.attributes.InstrumentedAttribute的实例之外,我需要跳过它们。在检查类字典时有没有办法区分这两者?
我找到的大多数关于sqlalchemy内省的文档都涉及查看metadata.table,但由于我正在重命名列,因此该数据不是易于映射的。
3个回答

7

每个映射实体的映射器都具有一个名为columns的属性,其中包含所有列定义。例如,如果您有一个声明类User,则可以使用User.__mapper__访问映射器,并使用以下代码访问列:

list(User.__mapper__.columns)

每个列都有几个属性,包括name(可能与映射属性命名为key的属性名称不同),nullableunique等等...


这似乎比检查metadata.tables['mytable'].columns更普遍有用,但它似乎不允许我发现描述符分配给实体类中的类变量,因此我仍然面临最初的问题,如何生成将类属性名称映射到其值的输出。 - Seamus Campbell

1
一个InstrumentedAttribute实例有一个名为impl的属性,实际上是一个ScalarAttributeImplScalarObjectAttributeImplCollectionAttributeImpl
我不确定这样做有多脆弱,但我只需检查它是哪个,就可以确定一个实例最终会返回列表还是单个对象。

1

我仍然希望看到这个问题的答案,但我已经通过对关系访问器进行名称混淆(例如使用“_otherentity”而不是“otherentity”)并在名称上进行过滤来解决了它。对于我的目的来说,这样做很好用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接