Nano Hash - криптовалюты, майнинг, программирование

Изменение массива результатов Flask-Restless

У меня есть что-то вроде этого:

{
  "id": 1, 
  "username": "plasmy",
  "userdetails": [
    {
      "detail": "A Name", 
      "detail_name": "Full Name", 
      "id": 1, 
      "user_id": 1
    }, 
    {
      "detail": "[email protected]", 
      "detail_name": "Email", 
      "id": 2, 
      "user_id": 1
    }, 
    {
      "detail": "An Address", 
      "detail_name": "Address", 
      "id": 3, 
      "user_id": 1
    }, 
    {
      "detail": "999-999-9999", 
      "detail_name": "Phone Number", 
      "id": 4, 
      "user_id": 1
    }
  ]
}

Это происходит в результате использования Flask_Restless и SQLAlchemy. Существует таблица для пользователей и таблица для сведений о пользователе, которые помещаются в часть сведений о пользователе этого JSON. Что я хочу сделать, так это найти способ, которым данные могут выглядеть так:

{
  "id": 1, 
  "username": "plasmy",
  "userdetails": {
      "Full Name": "A Name",
      "Email": "[email protected]",
      "Address": "An Address",
      "Phone Number": "A Phone Number"
    }
}

Посмотрите, как я удалил идентификаторы и использовал поле «detail_name» в качестве ключа и «detail» в качестве значения. Я пытался использовать препроцессоры, но они не работали, или, может быть, я их неправильно использую. Я поместил препроцессор в «дочернюю» таблицу.

Это то, что я пытался сделать (но не сработало):

def detail_sort(results):
    return {'user_details': results['userdetails']}


manager.create_api(User, methods=['GET', 'POST'])
manager.create_api(UserDetails, methods=['GET', 'POST'],
                   preprocessors={
                       'GET_COLLECTION': [detail_sort]
                   })

Я пробовал GET_COLLECTION, GET_SINGLE и GET_MANY. Любая помощь в этом будет принята с благодарностью.

ОБНОВЛЕНИЕ: вот новый код, который я попробовал на основе ответа

from flask import Blueprint
from medinv import manager
from medinv.User.models import User, UserDetails

blueprint = Blueprint('blueprint', __name__)


@blueprint.route('/')
@blueprint.route('/home')
def home():
    return "Welcome."


def detail_sort(results):
    print(results)
    results['userdetails'] = {item['detail_name']: item['detail'] for item in results['userdetails']}
    return results['userdetails']


manager.create_api(User, methods=['GET', 'POST'])
manager.create_api(UserDetails, methods=['GET', 'POST'],
                   postprocessors={
                       'GET_COLLECTION': [detail_sort]
                   })

Ответы:


1

Я думаю, вам нужно использовать постпроцессоры, так как вам нужно изменить ответ json перед его отправкой обратно клиенту.

Хорошо, я воспроизвел вашу проблему. Теперь это работает. Вот мой код:

import flask
import flask_sqlalchemy
import flask_restless

# Create the Flask application and the Flask-SQLAlchemy object.
app = flask.Flask(__name__)
app.config['DEBUG'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = flask_sqlalchemy.SQLAlchemy(app)


# Create your Flask-SQLALchemy models as usual but with the following
# restriction: they must have an __init__ method that accepts keyword
# arguments for all columns (the constructor in
# flask_sqlalchemy.SQLAlchemy.Model supplies such a method, so you
# don't need to declare a new one).

class User(db.Model):

    __tablename__ = 'user'

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String)
    userdetails = db.relationship('UserDetails', backref='User', lazy='dynamic')


class UserDetails(db.Model):

    __tablename__ = 'user_details'

    id = db.Column(db.Integer, primary_key=True)
    detail = db.Column(db.String)
    detail_name = db.Column(db.String)
    user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)

# Create the database tables.
db.create_all()

# Create the Flask-Restless API manager.
manager = flask_restless.APIManager(app, flask_sqlalchemy_db=db)

user = User(username='plasmy')
userdetail_0 = UserDetails(detail='A name', detail_name='Full Name' )
userdetail_1 = UserDetails(detail='[email protected]', detail_name='Email')
userdetail_2 = UserDetails(detail='An Address', detail_name='Address')
userdetail_3 = UserDetails(detail='999-999-9999', detail_name='Phone Number')


user.userdetails.append(userdetail_0)
user.userdetails.append(userdetail_1)
user.userdetails.append(userdetail_2)
user.userdetails.append(userdetail_3)

db.session.add(user)
db.session.commit()

print('USER CREATED')

def detail_sort(result, **kw):
    print('detail_sort called')
    print(result)

    for entry in result['objects']:
        entry['userdetails'] = {item['detail_name']: item['detail'] for item in
                                entry['userdetails']}
    print('MODIFIED JSON: ', result)

# Create API endpoints, which will be available at /api/<tablename> by
# default. Allowed HTTP methods can be specified as well.
# manager.create_api(Person, methods=['GET', 'POST', 'DELETE'])
# manager.create_api(Article, methods=['GET'])

manager.create_api(User, methods=['GET', 'POST', 'DELETE'],
                   postprocessors={
                       'GET_MANY': [detail_sort]
                   })
manager.create_api(UserDetails, methods=['GET'], )

# start the flask loop
app.run(use_reloader=False)

Обратите внимание, что вам нужно использовать GET_MANY и посмотреть, как реализовано detail_sort.

Без использования постпроцессора ответ будет таким:

{
  "num_results": 1, 
  "objects": [
    {
      "id": 1, 
      "userdetails": [
        {
          "detail": "A name", 
          "detail_name": "Full Name", 
          "id": 1, 
          "user_id": 1
        }, 
        {
          "detail": "[email protected]", 
          "detail_name": "Email", 
          "id": 2, 
          "user_id": 1
        }, 
        {
          "detail": "An Address", 
          "detail_name": "Address", 
          "id": 3, 
          "user_id": 1
        }, 
        {
          "detail": "999-999-9999", 
          "detail_name": "Phone Number", 
          "id": 4, 
          "user_id": 1
        }
      ], 
      "username": "plasmy"
    }
  ], 
  "page": 1, 
  "total_pages": 1
}

С постпроцессором ответ выглядит так:

{
  "num_results": 1, 
  "objects": [
    {
      "id": 1, 
      "userdetails": {
        "Address": "An Address", 
        "Email": "[email protected]", 
        "Full Name": "A name", 
        "Phone Number": "999-999-9999"
      }, 
      "username": "plasmy"
    }
  ], 
  "page": 1, 
  "total_pages": 1
}

Надеюсь это поможет.

13.06.2017
  • Спасибо за ваш ответ. Я пробовал это, и это не сработало. Я собираюсь отредактировать свой код views.py в исходном посте, чтобы увидеть, видите ли вы что-то не так. Кроме того, часть, в которой говорится, что results['userdetails'] = .... выдает мне ошибку, говоря, что это невозможно. Я попытался немного изменить его, чтобы возвращать только результаты ['userdetails'], и ошибка исчезла, но она все еще не работает. На самом деле я пытался сделать печать, и она не доходит до подробностей. 13.06.2017
  • @plasmy Что вы получаете как ошибку? Попробуйте сначала установить значение для ключевых сведений о пользователе в результатах, а затем вернуть его. Я не тестировал свой код. 13.06.2017
  • Да, я пробовал это, и ошибка не появляется. Проблема в том, что он все еще не делает то, что я хочу. 13.06.2017
  • @plasmy Не могли бы вы вставить трассировку стека ошибки? 13.06.2017
  • Traceback (most recent call last): File "run.py", line 1, in <module> from medinv import app File "/Users/myname/PycharmProjects/MedInvAPI/medinv/__init__.py", line 10, in <module> from medinv.User.views import blueprint File "/Users/myname/PycharmProjects/MedInvAPI/medinv/User/views.py", line 15 return results['userdetails'] = {item['detail_name']: item['detail'] for item in results['userdetails']} ^ SyntaxError: invalid syntax Я отредактировал код, чтобы показать, как я исправил эту ошибку. С этим кодом я не получаю ошибку. 13.06.2017
  • @plasmy Если сейчас ошибки нет, что произойдет с результатами? Вы распечатали его? 13.06.2017
  • Это не модифицирует его, как я хочу. Я даже пытался выполнить печать, но это как будто никогда не получается, потому что печать никогда не выполняется. 13.06.2017
  • @plasmy Вы пытались добавить постпроцессор для пользователя, но не для UserDetails в вызове create_api()? 13.06.2017
  • Это было прекрасно! Я немного изменил код, так как он работал только для одной записи. Я также добавил GET_SINGLE в постпроцессоры, а в detail_sort я сделал проверку if на наличие «объекта» в результате. Если он существует, то он выполняет ваш код, а если нет, то это почти тот же код, но без первого foreach. Большое спасибо!!!! 13.06.2017
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..