SQLAlchemy的列到行变换,反之亦然 - 这可能吗?
-
21-09-2019 - |
题
我正在寻找一个只SQLAlchemy的溶液在数据库中,一个用于提交每个字段从表单提交接收一个字典转换成一系列行。这是处理的喜好和设置,应用程序之间有很大的不同。但是,它很可能适用于创建数据透视表一样的功能。我见过这种类型的事情在ETL工具,但我一直在寻找一种方式来直接在ORM做到这一点。我找不到它的任何文件,但也许我错过了什么。
示例:
从表单提交:{ “唯一ID为”:1, “A”:23, “B”: “你好”, “C”: “世界”}
我想它被转换(在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方法。
预先感谢...
干杯,
保
解决方案
下面是从文档略加修改的示例与模型映射到词典这样的表结构的工作:
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()
不隶属于 StackOverflow