В Django есть несколько хороших автоматических сериализаций моделей ORM, возвращаемых из DB в формат JSON.
Как сериализовать результат запроса SQLAlchemy в формат JSON?
Я пытался, jsonpickle.encode
но он сам кодирует объект запроса. Я пытался, json.dumps(items)
но это возвращает
TypeError: <Product('3', 'some name', 'some desc')> is not JSON serializable
Неужели так сложно сериализовать объекты SQLAlchemy ORM в JSON / XML? Нет ли для этого сериализатора по умолчанию? В настоящее время очень распространена задача сериализации результатов запроса ORM.
Что мне нужно, так это просто вернуть JSON или XML представление данных результата запроса SQLAlchemy.
Результат запроса объектов SQLAlchemy в формате JSON / XML необходим для использования в javascript datagird (JQGrid http://www.trirand.com/blog/ )
python
json
sqlalchemy
Zelid
источник
источник
Ответы:
Плоская реализация
Вы можете использовать что-то вроде этого:
а затем преобразовать в JSON, используя:
Он будет игнорировать поля, которые не кодируются (установите для них значение «Нет»).
Он не расширяет отношения автоматически (поскольку это может привести к самоссылке и циклу навсегда).
Рекурсивная, некруглая реализация
Однако, если вы предпочитаете цикл навсегда, вы можете использовать:
А затем кодировать объекты с помощью:
Это закодирует всех детей, и всех их детей, и всех их детей ... Потенциально, в основном, закодируйте всю вашу базу данных. Когда он достигает чего-то, что было закодировано ранее, он будет кодировать его как «Нет».
Рекурсивная, возможно круговая, выборочная реализация
Другая альтернатива, возможно, лучше, это возможность указать поля, которые вы хотите расширить:
Теперь вы можете позвонить с помощью:
Например, чтобы расширить только поля SQLAlchemy, называемые «родители».
источник
online_order
и тоaddress
, и другое связано сuser
, ноonline_order
также имеет отношение кaddress
. Если бы я хотел сериализовать все это, я бы включилaddress
в негоfields_to_expand
, но я не хотел бы избыточно сериализоватьaddress
из-за его отношения к обоимuser
иonline_order
.for field in [x for x in dir(obj) if not x.startswith('_') and x != 'metadata']:
его следующим образомfor field in [x for x in dir(obj) if not x.startswith('_') and x != 'metadata' and not x.startswith('query')]:
. Имейте в виду, что это решение не позволит вам иметь свойство / отношения с именем 'query'Вы можете просто вывести свой объект в виде словаря:
А затем вы используете
User.as_dict()
для сериализации вашего объекта.Как объясняется в разделе Конвертировать объект строки sqlalchemy в python dict
источник
JSONEncoder
объекта. Вы можете создать его подкласс, чтобы определить свой собственный кодер для некоторого объекта, включая datetime. Обратите внимание, чтоFlask
, например, встроенная поддержка даты и времени в формате JSON (с последней версией).return {c.name: unicode(getattr(self, c.name)) for c in self.__table__.columns}
Вы можете преобразовать RowProxy в dict следующим образом:
Затем сериализуйте это в JSON (вам нужно будет указать кодировщик для таких вещей, как
datetime
значения). Это не так сложно, если вы просто хотите одну запись (и не полную иерархию связанных записей).источник
Я рекомендую использовать зефир . Это позволяет вам создавать сериализаторы для представления экземпляров вашей модели с поддержкой отношений и вложенных объектов.
Вот усеченный пример из их документов. Возьмите модель ORM
Author
:Схема зефира для этого класса строится так:
... и используется так:
... будет производить вывод, как это:
Взгляните на их полный пример Flask-SQLAlchemy .
Библиотека под названием
marshmallow-sqlalchemy
специально объединяет SQLAlchemy и зефир. В этой библиотеке схема дляAuthor
модели, описанной выше, выглядит следующим образом:Интеграция позволяет выводить типы полей из
Column
типов SQLAlchemy .Зефир-sqlalchemy здесь.
источник
Python 3.7+ и Flask 1.1+ могут использовать встроенный пакет dataclasses
/users/
Маршрут теперь будет возвращать список пользователей.Автосериализация связанных моделей
Ответ
jsonify(account)
будет таким.Перезаписать JSON Encoder по умолчанию
источник
data = request.json['user']; user = User(**data)
id: int = Column
это сработает, ноid = Column
не сработает, похоже, вам нужно объявить статическую типизацию для json, чтобы сериализовать поле, в противном случае вы получите пустой{}
объект.pipenv install dataclasses
. И тогда это будет работать просто отлично.В пакете Flask-JsonTools есть реализация базового класса JsonSerializableBase для ваших моделей.
Использование:
Теперь
User
модель магически сериализуема.Если ваш фреймворк не Flask, вы можете просто взять код
источник
import flask.ext.whatever
больше не поддерживается в Flask 1.0.Из соображений безопасности вы никогда не должны возвращать все поля модели. Я предпочитаю выборочно выбирать их.
JSON КОЛБА в кодирующем теперь поддерживает UUID, DateTime и отношения (и добавляемый
query
иquery_class
для flask_sqlalchemydb.Model
класса). Я обновил кодировщик следующим образом:При этом я могу при желании добавить
__json__
свойство, которое возвращает список полей, которые я хочу кодировать:Я добавляю @jsonapi к своему представлению, возвращаю список результатов, и затем мой вывод выглядит следующим образом:
источник
@jsonapi
к@app.route
в views.py и т.д.), но я люблю простоту этого. Я думаю, что это дешевый Flask, добавленный datetime, но не date, поэтому я добавил его сам в json_encoder.py :value=...
^if isinstance(value, date):
^data[field] = datetime.combine(value, time.min).isoformat()
^else:
^try:...
Вы можете использовать самоанализ SqlAlchemy так:
Получите вдохновение от ответа здесь: Конвертируйте объект строки sqlalchemy в python dict
источник
Более подробное объяснение. В вашей модели добавьте:
Это
str()
для Python 3, поэтому при использовании Python 2 используйтеunicode()
. Это должно помочь десериализировать даты. Вы можете удалить его, если не имеете дела с ними.Теперь вы можете запросить базу данных, как это
First()
необходимо, чтобы избежать странных ошибок.as_dict()
теперь будет десериализовать результат. После десериализации он готов к обращению в jsonисточник
Это не так просто. Я написал код для этого. Я все еще работаю над этим, и он использует фреймворк MochiKit. Он в основном транслирует составные объекты между Python и Javascript, используя прокси и зарегистрированные JSON-конвертеры.
Сторона браузера для объектов базы данных - db.js. Для него нужен базовый источник прокси Python в proxy.js .
На стороне Python есть базовый прокси-модуль . Затем, наконец, объектный кодировщик SqlAlchemy в webserver.py . Это также зависит от экстракторов метаданных, найденных в файле models.py .
источник
В то время как первоначальный вопрос возвращается некоторое время назад, количество ответов здесь (и мой собственный опыт) позволяют предположить, что это нетривиальный вопрос с множеством различных подходов различной сложности с различными компромиссами.
Вот почему я создал библиотеку SQLAthanor, которая расширяет декларативную ORM SQLAlchemy с настраиваемой поддержкой сериализации / десериализации , на которую вы, возможно, захотите взглянуть.
Библиотека поддерживает:
dict
password
значение, но никогда не включать исходящее )Вы можете ознакомиться с (я надеюсь!) Исчерпывающими документами здесь: https://sqlathanor.readthedocs.io/en/latest
Надеюсь это поможет!
источник
Пользовательские сериализация и десериализация.
from_json (метод класса) создает объект Model на основе данных json.
«Десериализация» может быть вызвана только в экземпляре и объединить все данные из json в экземпляр модели.
"serialize" - рекурсивная сериализация
Свойство __write_only__ необходимо для определения свойств только для записи (например, «password_hash»).
источник
Вот решение, которое позволяет вам выбрать отношения, которые вы хотите включить в свой вывод, настолько глубоко, насколько вы хотели бы. ПРИМЕЧАНИЕ. Это полная перезапись, в которой в качестве аргумента используется аргумент dict / str, а не список. исправляет некоторые вещи ..
так, например, используя человека / семью / дома / комнаты ... превращая его в JSON, все, что вам нужно, это
источник
Я думал, что поиграю в маленький гольф с этим.
К вашему сведению: я использую automap_base, так как у нас есть отдельно разработанная схема в соответствии с требованиями бизнеса. Я только что начал использовать SQLAlchemy сегодня, но в документации говорится, что automap_base является расширением декларативной_базы, которая, кажется, является типичной парадигмой в ORM SQLAlchemy, поэтому я считаю, что это должно работать.
Ему не нравятся следующие внешние ключи для решения Tjorriemorrie , но он просто сопоставляет столбцы со значениями и обрабатывает типы Python с помощью str () - значений столбцов. Наши значения состоят из Python datetime.time и decimal.Decimal, результаты типа класса, поэтому он выполняет свою работу.
Надеюсь, это поможет любому прохожему!
источник
Я знаю, что это довольно старый пост. Я принял решение, данное @SashaB, и изменил его в соответствии с моими потребностями.
Я добавил следующие вещи к нему:
Мой код выглядит следующим образом:
Надеюсь, это поможет кому-то!
источник
Используйте встроенный сериализатор в SQLAlchemy:
Если вы переносите объект между сеансами, не забудьте отсоединить объект от текущего сеанса с помощью
session.expunge(obj)
. Чтобы прикрепить его снова, просто сделайтеsession.add(obj)
.источник
следующий код будет сериализовать результат sqlalchemy в json.
Вызывая веселье,
источник
AlchemyEncoder замечательный, но иногда терпит неудачу с десятичными значениями. Вот улучшенный кодер, который решает десятичную проблему -
источник
При использовании sqlalchemy для подключения к БД I это простое решение, которое легко настраивается. Используйте панд.
источник
источник
Под Flask это работает и обрабатывает поля времени данных, превращая поле типа
'time': datetime.datetime(2018, 3, 22, 15, 40)
в"time": "2018-03-22 15:40:00"
:источник
Встроенные дроссели сериализатора с utf-8 не могут декодировать недопустимый начальный байт для некоторых входов. Вместо этого я пошел с:
источник
Может быть, вы можете использовать такой класс
При этом все объекты имеют
to_dict
методисточник
Используя некоторые необработанные sql и неопределенные объекты, я использовал,
cursor.description
чтобы получить то, что я искал:источник
Мой дубль, использующий (слишком много?) Словарей:
Запуск с flask (включая jsonify) и flask_sqlalchemy для печати выводов в формате JSON.
Вызовите функцию с помощью jsonify (serialize ()).
Работает со всеми запросами SQLAlchemy, которые я пробовал до сих пор (работает SQLite3)
источник