7

いくつかの軽量データ変換(主にフィールド名の変更)を使用してMySQLデータベースからデータをエクスポートするための小さなsqlalchemyシムを作成しています。現在のスクリプトは正常に機能しますが、基本的にモデルを2回記述する必要があります。1回はクラス宣言で、もう1回は反復するフィールド名のリストとして記述します。

イントロスペクションを使用して、列アクセサーである行オブジェクトのプロパティを識別する方法を理解しようとしています。以下はほぼ完璧に機能します。

for attr, value in self.__class__.__dict__.iteritems():
    if isinstance(value, sqlalchemy.orm.attributes.InstrumentedAttribute):
        self.__class__._columns.append(attr)

ただし、to-manyリレーションアクセサーはsqlalchemy.orm.attributes.InstrumentedAttributeのインスタンスでもあり、それらをスキップする必要があります。クラス辞書を調べているときに、この2つを区別する方法はありますか?

sqlalchemyのイントロスペクションで見つけたドキュメントのほとんどは、metadata.tableを調べることを含みますが、列の名前を変更しているため、そのデータは簡単にマッピングできません。

4

3 に答える 3

7

マップされた各エンティティの Mapper には、columnsすべての列定義を持つ属性があります。たとえば、宣言型クラスがあるUser場合は、マッパーとUser.__mapper__列に次のようにアクセスできます。

list(User.__mapper__.columns)

各列には、name( という名前のマップされた属性と同じではない可能性がありますkey) 、 などnullable、いくつかの属性がありuniqueます...

于 2010-08-01T05:26:24.963 に答える
1

An InstrumentedAttribute instance has an an attribute called impl that is in practice a ScalarAttributeImpl, a ScalarObjectAttributeImpl, or a CollectionAttributeImpl.

I'm not sure how brittle this is, but I just check which one it is to determine whether an instance will ultimately return a list or a single object.

于 2012-08-30T21:09:01.747 に答える
1

私はまだこの質問に対する答えを見たいと思っていますが、リレーションシップ アクセサーの名前をマングリングし (たとえば、'otherentity' ではなく '_otherentity')、名前でフィルター処理することで回避しました。私の目的には問題なく動作します。

于 2010-08-01T05:14:20.433 に答える