TL; DR 使用SQLAlchemy是否可以使用dumps(…)
and load(…)
(而不是Table
)进行mapped class?为了澄清,我写了two tiny tests (currently red)来表达我的观点。
拥有此映射的类和会话:
<h3>Animals:</h3>
<ul id="animal"></ul>
使用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
这条消息已经太长了,所以我避免谈论有关问题的背景。但我确实有a situation我需要转储和加载非映射类......我正试图找到一个解决方案。 (免责声明:2年前,当我是Python的新手时,我写了这个包;是的,代码看起来很糟糕 - 但我在过去几周里一直在完全重构它。)
SQLAlchemy中这个新手的任何想法或建议?
答案 0 :(得分:0)
在@ univerio的评论之后,我可以更好地了解情况并修复,是的!
问题是,如果SQLAlchemy dumps
收到Table
实例,结果与表无关,则它们纯粹是KeyedTuple
。所以我不得不:
KeyedTuple
加载KeyedTuple
转换为字典(这很简单,因为KeyedTuple
有_asdict()
方法)tests are now green,但总结一下这就是我所需要的:
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()