我有一个存储在文本列中的JSON表:
import json
from sqlalchemy import create_engine, Column, text, Integer, TEXT, TypeDecorator
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
engine = create_engine('sqlite:///:memory:')
engine.execute("create table t (t_id int not null primary key, attrs text not null)")
engine.execute("insert into t values (1, '{\"a\": 1, \"b\": 2}')")
Session = sessionmaker(bind=engine)
我使用SQLAlchemy文档中“Marshal JSON Strings”下定义的自定义类型在SQLAlchemy中定义了此表的映射:
Base = declarative_base()
# http://docs.sqlalchemy.org/en/rel_1_1/core/custom_types.html#marshal-json-strings
class JSONEncodedDict(TypeDecorator):
impl = TEXT
def process_bind_param(self, value, dialect):
if value is not None:
value = json.dumps(value)
return value
def process_result_value(self, value, dialect):
if value is not None:
value = json.loads(value)
return value
class T(Base):
__tablename__ = 't'
t_id = Column(Integer, primary_key=True)
attrs = Column(JSONEncodedDict)
如果我查询所有T
,则{J}对attrs
进行反序列化:
session = Session()
t = session.query(T).first()
assert type(t.attrs) == dict, repr(t.attrs)
但是如果我使用文本查询/原始SQL,则不会反序列化:
session = Session()
t = session.query(T).from_statement(text('select * from t')).first()
assert type(t.attrs) == dict, repr(t.attrs) # AssertionError: u'{"a": 1, "b": 2}'
在使用原始SQL查询时,如何使SQLAlchemy反序列化attrs
列?
行为与其他数据库(MySQL,Postgres)相同。我正在使用的数据库(MySQL 5.5)不支持本机JSON类型,因此不能选择更改列类型。
答案 0 :(得分:1)
您可以使用.columns()
告诉TextClause
(text()
)列类型:
from sqlalchemy import inspect
session = Session()
stmt = text('select * from t').columns(*inspect(T).columns)
t = session.query(T).from_statement(stmt).first()
assert type(t.attrs) == dict, repr(t.attrs)
或者,对于SQLAlchemy< 0.9,请使用typemap参数:
from sqlalchemy import inspect
session = Session()
typemap = {c.name: c.type for c in inspect(T).columns}
stmt = text('select * from t', typemap=typemap)
t = session.query(T).from_statement(stmt).first()
assert type(t.attrs) == dict, repr(t.attrs)