TL; DR 사용 SQLAlchemy의하면 그것은 할 수 dumps(…)
및load(…)
사용하여 A Table
(하지 매핑 클래스 )? 명확히하기 위해, 나는 내 요점 을 밝히기 위해 두 개의 작은 테스트 (현재 빨간색) 를 작성했습니다.
이 매핑 된 클래스 및 세션이있는 경우 :
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.serializer import loads, dumps
from sqlalchemy.orm import mapper, scoped_session
from sqlalchemy.orm.session import sessionmaker
engine = create_engine('sqlite:///:memory:', echo=False)
Base = declarative_base(bind=engine)
session = scoped_session(sessionmaker())
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
email = Column(String(140), index=True, unique=True)
User
매핑 된 클래스를 사용하여 데이터를 덤프하고로드 할 수 있습니다.
>>> # create a record
>>> Base.metadata.create_all()
>>> session.add(User(email='john@alchemydumps'))
>>> session.commit()
>>>
>>> # use dumps
>>> with open('dummy_file', 'wb') as file_handler:
... file_handler.write(dumps(session.query(User).all()))
...
490
>>>
>>> # reset the database
>>> Base.metadata.drop_all()
>>> Base.metadata.create_all()
>>>
>>> # use loads
>>> with open('dummy_file', 'rb') as file_handler:
... for row in loads(file_handler.read()):
... session.merge(row)
...
<__main__.User object at 0x10977ea20>
>>> session.commit()
>>>
>>> # assert data is back
>>> session.query(User).count()
1
>>>
그러나 Table
대신 사용하면 작동 하지 않습니다 .
>>> …
>>>
>>> # use a table instead (User.__table__, instead of User)
>>> with open('dummy_file', 'wb') as file_handler:
... file_handler.write(dumps(session.query(User.__table__).all()))
...
115
>>> Base.metadata.drop_all()
>>> Base.metadata.create_all()
>>>
>>> with open('dummy_file', 'rb') as file_handler:
... for row in loads(file_handler.read()):
... session.merge(row)
...
이 코드는 sqlalchemy.orm.exc.UnmappedInstanceError
다음 과 충돌합니다 .
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
File "/Users/cuducos/.virtualenvs/alchemydumps/lib/python3.5/site-packages/sqlalchemy/orm/scoping.py", line 157, in do
return getattr(self.registry(), name)(*args, **kwargs)
File "/Users/cuducos/.virtualenvs/alchemydumps/lib/python3.5/site-packages/sqlalchemy/orm/session.py", line 1702, in merge
object_mapper(instance) # verify mapped
File "/Users/cuducos/.virtualenvs/alchemydumps/lib/python3.5/site-packages/sqlalchemy/orm/base.py", line 266, in object_mapper
return object_state(instance).mapper
File "/Users/cuducos/.virtualenvs/alchemydumps/lib/python3.5/site-packages/sqlalchemy/orm/base.py", line 288, in object_state
raise exc.UnmappedInstanceError(instance)
sqlalchemy.orm.exc.UnmappedInstanceError: Class 'sqlalchemy.util._collections.KeyedTuple' is not mapped
이 메시지는 이미 너무 깁니다. 그래서 저는 probelm의 맥락에 대해 많이 이야기하지 않았습니다. 하지만 매핑되지 않은 클래스를 덤프하고로드해야하는 상황 이 있습니다. 이에 대한 해결책을 찾으려고합니다. ( 면책 조항 : 2 년 전 Python 초보자 였을 때이 패키지를 작성했습니다. 예, 코드가 끔찍해 보이지만 지난 몇 주 동안 완전히 리팩토링했습니다. )
SQLAlchemy에서이 초보자에 대한 아이디어 나 권장 사항이 있습니까?
@univerio의 댓글 후에 나는 상황을 더 잘 이해하고 고칠 수있었습니다.
문제는 SQLAlchemy dumps
가 Table
인스턴스를 수신 하면 결과가 테이블과 관련이 없으며 순전히 KeyedTuple
. 그래서 나는 :
KeyedTuple
로드 되었을 때 매핑 된 클래스 가져 오기KeyedTuple
사전에 (용이 한 바와 같이 KeyedTuple
갖는 _asdict()
법)테스트는 지금 녹색 , 그러나 이것은 내가 필요로 무엇 요약 :
with open('dummy_file', 'rb') as file_handler:
... for row in loads(file_handler.read()):
... if isinstance(row, KeyedTuple):
... row = User(**row._asdict())
... session.merge(row)
>>> session.commit()
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다