5

フォーム送信から受け取ったdictを、送信されたフィールドごとに1つずつ、データベース内の一連の行に変換するためのSQLAlchemyのみのソリューションを探しています。これは、アプリケーション間で大きく異なる設定と設定を処理するためのものです。ただし、ピボットテーブルのような機能の作成に適用できる可能性が非常に高くなります。私はETLツールでこの種のことを見てきましたが、ORMで直接それを行う方法を探していました。ドキュメントが見つかりませんでしたが、何かが足りなかったのかもしれません。

例:

フォームから送信:{"UniqueId":1、 "a":23、 "b": "Hello"、 "c": "World"}

次のようにデータベースに記録されるように(ORMで)変換したいと思います。

_______________________________________
|UniqueId| ItemName   | ItemValue     |
---------------------------------------
|  1     |    a       |    23         |
---------------------------------------
|  1     |    b       |    Hello      |
---------------------------------------
|  1     |    c       |    World      |
---------------------------------------

選択すると、結果は(ORMで)個々の値のそれぞれからのデータの行に変換されます。

---------------------------------------------------
| UniqueId  |  a     |     b      |       c       |

---------------------------------------------------
|   1       |  23    |   Hello    |   World       |

---------------------------------------------------

更新時に、現在のレコードが削除され、新しいレコードが挿入されるように、トランザクションで削除/作成をラップすることが最善のアクションであると想定します。

ItemNamesの決定的なリストは、別のテーブルに保持されます。

より洗練されたソリューションに完全にオープンですが、可能な限りデータベース側から遠ざけたいと考えています。

SQLAlchemyでdeclarative_baseアプローチを使用しています。

前もって感謝します...

乾杯、

ポール

4

1 に答える 1

9

モデル内のディクショナリにマップされたテーブル構造を操作するために、ドキュメントからわずかに変更された例を次に示します。

from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm.collections import attribute_mapped_collection
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm import relation, sessionmaker

metadata  = MetaData()
Base = declarative_base(metadata=metadata, name='Base')

class Item(Base):

    __tablename__ = 'Item'
    UniqueId = Column(Integer, ForeignKey('ItemSet.UniqueId'),
                      primary_key=True)
    ItemSet = relation('ItemSet')
    ItemName = Column(String(10), primary_key=True)
    ItemValue = Column(Text) # Use PickleType?

def _create_item(ItemName, ItemValue):
    return Item(ItemName=ItemName, ItemValue=ItemValue)

class ItemSet(Base):

    __tablename__ = 'ItemSet'
    UniqueId = Column(Integer, primary_key=True)
    _items = relation(Item,
                      collection_class=attribute_mapped_collection('ItemName'))
    items = association_proxy('_items', 'ItemValue', creator=_create_item)

engine = create_engine('sqlite://', echo=True)
metadata.create_all(engine)

session = sessionmaker(bind=engine)()
data = {"UniqueId": 1, "a": 23, "b": "Hello", "c": "World"}
s = ItemSet(UniqueId=data.pop("UniqueId"))
s.items = data
session.add(s)
session.commit()
于 2010-01-19T11:35:26.413 に答える