Как создать sqlalchemy для json
У меня есть результат sqlalchemy
labels = session.query(
LabelsData,
LabelsData.id,
LabelsData.name,
LabelsData.color
).filter(LabelsData.deleted==False).all()
и я хочу преобразовать этот результат в JSON, но как я могу это сделать?
6 ответов
это выглядит как ваш LabelsData
объект является моделью SQLAlchemy. Вам нужно сериализовать его, прежде чем сбрасывать его в JSON. Вот краткий пример, который извлекает все столбцы из вашего LabelsData
объект и преобразует результаты вашего запроса в JSON:
from json import dumps
from sqlalchemy.orm import class_mapper
def serialize(model):
"""Transforms a model into a dictionary which can be dumped to JSON."""
# first we get the names of all the columns on your model
columns = [c.key for c in class_mapper(model.__class__).columns]
# then we return their values in a dict
return dict((c, getattr(model, c)) for c in columns)
# we can then use this for your particular example
serialized_labels = [
serialize(label)
for label in session.query(LabelsData).filter(LabelsData.deleted == False)
]
your_json = dumps(serialized_labels)
from collections import OrderedDict
class DictSerializable(object):
def _asdict(self):
result = OrderedDict()
for key in self.__mapper__.c.keys():
result[key] = getattr(self, key)
return result
С здесь и, кажется, требует simplejson. Надеюсь, это поможет...
UPDATE: на второй взгляд, это словарь, который вы can дамп любым из модулей json в python.
похоже, что sqlalchemy уже имеет один http://docs.sqlalchemy.org/en/latest/core/serializer.html
from sqlalchemy.ext.serializer import loads, dumps
metadata = MetaData(bind=some_engine)
Session = scoped_session(sessionmaker())
# ... define mappers
query = Session.query(MyClass).filter(MyClass.somedata=='foo').order_by(MyClass.sortkey)
# pickle the query
serialized = dumps(query)
# unpickle. Pass in metadata + scoped_session
query2 = loads(serialized, metadata, Session)
print query2.all()
в этом блоге не пошел с: http://blogs.gnome.org/danni/2013/03/07/generating-json-from-sqlalchemy-objects/
используемая стратегия должна была включать a .метод todict непосредственно к базовому mixin, который выполняет итерацию по столбцам SQLAlchemy родительского класса.
кроме того, НандеС (https://stackoverflow.com/a/19602809/837575) для использования с SQLAlchemy.доб.сериализатор работает хорошо, если вы пытаетесь для сериализации данных по проводу, но не обязательно это нужно как json.
я добавляю этот anwser, поскольку это смесь @mekarpeles и @hd1. Я имею в виду, что я не изменил иерархию объектов sqlalchemy, просто делегируя простой JSONEncoder:
# given that you have
Base = declarative_base()
class SqlAlchemyModelEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Base):
result = OrderedDict()
for key in obj.__mapper__.c.keys():
result[key] = getattr(obj, key)
return result
return json.JSONEncoder.default(self, obj)
Если ваши модели используют несериализуемые классы (например, datetime), вы должны добавить их в кодировщик :
if isinstance(obj, datetime):
return obj.isoformat()
и затем я использую его с контекстным фильтром jinja2:
@contextfilter
def tojson(ctx, model, *elements, **kw):
return json.dumps(model, cls=SqlAlchemyModelEncoder)
https://github.com/TaylorHere/PythonSerializer
ссылка выше может дать вам руку, это небольшой скрипт, который может просто сериализовать результат sql-запроса в список или дикт, вот так:
#Useage with flask and SQLalchemy
from serializer import serializer
def my_location():
if request.method == 'GET':
user = db_session.query(User).filter(
User.openid == session['user_id']).first()
addresses = user.addresses
return jsonify({'data': serializer(addresses.instance, 'sqlalchemy')})