2010-01-18 5 views
4

양식 제출에서받은 dict를 데이터베이스의 일련의 행 (각 제출 된 필드 당 하나씩)으로 변환하기위한 SQLAlchemy 전용 솔루션을 찾고 있습니다. 이는 응용 프로그램마다 크게 다른 환경 설정 및 설정을 처리하기위한 것입니다. 그러나 기능과 같은 피벗 테이블을 만드는 데 적용 할 가능성이 큽니다. ETL 도구에서 이런 유형의 것을 보았지만 ORM에서 직접 수행 할 방법을 찾고있었습니다. 그것에 대한 문서를 찾을 수는 없었지만 뭔가를 놓친 것 같습니다.SQLAlchemy 열에서 행으로 변환 및 그 반대로 가능합니까?

예 :

양식에서 제출 : { "UNIQUEID": 1, "A": 23, "B": "안녕하세요", "C": "세계"}

내가 좋아하는 것 이 같이 데이터베이스에 기록되어 있도록합니다 (ORM에서) 변형된다 :

의 각각에서 다시 데이터 행에 결과합니다 (ORM에서) 변환 될 선별시
_______________________________________ 
|UniqueId| ItemName | ItemValue  | 
--------------------------------------- 
| 1  | a  | 23   | 
--------------------------------------- 
| 1  | b  | Hello  | 
--------------------------------------- 
| 1  | c  | World  | 
--------------------------------------- 

개별 값.

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

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

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

내가 최선의 조치가/삭제를 감싸 현재 레코드가 제거되고 새가 삽입 될 수 있도록 트랜잭션에서 생성하는 것입니다 업데이 트에 가정 것이다.

ItemNames의 최종 목록은 별도의 테이블에서 관리됩니다.

완전히 우아한 솔루션으로 완전히 열리지 만 가능한 경우 데이터베이스 측면을 벗어나고 싶습니다.

SQLAlchemy에서 declarative_base 방식을 사용하고 있습니다. 사전에

감사합니다 ...

건배,

다음

답변

8

모델에서 사전에 매핑 같은 테이블 구조 작업 할 documentation에서 약간 수정 된 예입니다

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() 
+0

Brilliant Denis! 정확히 내가 무엇을 찾고 있었는지. 또한 훌륭한 실례를 추가해 주셔서 감사드립니다. association_proxy 항목을 이해하려고 많은 시간을 절약했습니다. – PlaidFan

관련 문제