1

Pythonメタクラスを使用してマッピングしている一連の動的データベーステーブル(PostGISを使用したPostgres 9.3)があります:

cls = type(str(tablename), (db.Model,), {'__tablename__':tablename})

ここで、db.Model はフラスコ sqlalchemy による db オブジェクトで、tablename は少しの Unicode です。cls はアプリケーション全体のディクショナリにcurrent_app.class_references(Flask の current_app を使用して) 追加され、クラスを複数回インスタンス化しようとする試みを回避します。

wkb_geometry各テーブルには、 Well Known Binaryに格納されたジオメトリ列が含まれています。これらをマップしてgeoalchemy2を使用し、GeoJSON を取得するという最終目標を達成したいと考えています。

テーブルをアプリオリに宣言する場合は、次を使用します。

class GeoPoly():
    __tablename__ = 'somename'
    wkb_geometry = db.Column(Geometry("POLYGON"))
    #more columns...

cls1これを動的に実行しようとしているので、既知の型でリフレクションをオーバーライドできる必要があります。

試み:

  1. リフレクション オーバーライド構文を使用して、列を明示的に定義します。

    cls = type(str(tablename), (db.Model,), {'__tablename__':tablename,
        'wkb_geometry':db.Column(Geometry("POLYGON"))})
    

新たに再起動すると、つまり、クラスはまだインスタンス化されていません: InvalidRequestError: テーブル 'tablename' は、この MetaData インスタンスに対して既に定義されています。'extend_existing=True' を指定して、既存のテーブル オブジェクトのオプションと列を再定義します

  1. 上で定義したクラスで mixin を使用します (sans tablename ):

    cls = type(str(tablename), (GeoPoly, db.Model), {'__tablename__':tablename})
    

再びメタデータの問題。

  1. クラスがインスタンス化された後、列定義属性をオーバーライドします。

    cls = type(str(tablename), (db.Model,), {'__tablename__':tablename})
    current_app.class_references[tablename] = cls
    cls.wkb_geometry = db.Column(Geometry("POLYGON"))
    

結果は次のとおりです。

InvalidRequestError: 属性 'wkb_geometry' の下で列 tablename.wkb_geometry を列 tablename.wkb_geometry と暗黙的に組み合わせています。これらの同じ名前の列の 1 つ以上の属性を明示的に構成してください。

メタデータ構造を使用して動的リフレクションをサポートし、*すべてのテーブルで使用できることがわかっている列をオーバーライドすることは可能ですか?

4

2 に答える 2