Я только начал работать с пакетом marshmallow-sqlalchemy на Python для своего приложения Flask. Все работает нормально, и api выплевывает содержимое моей базы данных, но, похоже, сортирует поля по алфавиту, а не в том порядке, в котором я их создал с помощью класса SQLAlchemy.Model. Теперь мне было интересно, есть ли способ запретить это или хотя бы отсортировать поля как-то вручную?

Вот как я создаю свою таблицу базы данных:

class Product(db.Model):
    p_id = db.Column(db.Integer, primary_key=True)
    p_name = db.Column(db.String(100), nullable=False)
    p_type = db.Column(db.String, nullable=False)
    p_size = db.Column(db.Integer, nullable=False)
    p_color = db.Column(db.String, nullable=False)

    def __repr__(self):
        return f"Product(name={self.p_name}, type={self.p_type}, size={self.p_size}, color={self.p_color})"

И это моя схема:

class ProductSchema(SQLAlchemyAutoSchema):
    class Meta:
        ordered = True     #I have read about this property on another post, but doesn't do anything here
        model = Product

Моя функция, возвращающая содержимое в формате json:

    def get(self, id):
        if id:
            product = Product.query.filter_by(p_id=id).first()
            if product:
                product_schema = ProductSchema()
                output = product_schema.dump(product)
            else:
                abort(Response('product not found', 400))
        else:
            products = Product.query.all()
            products_schema = ProductSchema(many=True)
            output = products_schema.dump(products)
        return jsonify(output), 200

Aa и вывод, который я получаю (отсортированный по алфавиту):

[
  {
    "p_color": "test color1", 
    "p_id": 1, 
    "p_name": "test name1", 
    "p_size": 8, 
    "p_type": "test type1"
  }, 
  {
    "p_color": "test color2", 
    "p_id": 2, 
    "p_name": "test name2", 
    "p_size": 8, 
    "p_type": "test type2"
  }, 
  {
    "p_color": "test color3", 
    "p_id": 3, 
    "p_name": "test name3", 
    "p_size": 8, 
    "p_type": "test type3"
  }, 
  {
    "p_color": "test color4", 
    "p_id": 4, 
    "p_name": "test name4", 
    "p_size": 8, 
    "p_type": "test type4"
  }
]

Как описано выше, мое приложение полностью работоспособно. Но я по крайней мере хотел бы знать, что происходит. Так что любая помощь приветствуется!

0
barbarossa 22 Фев 2021 в 00:45

1 ответ

Лучший ответ

По умолчанию Flask сортирует ключи при выгрузке вывода json. Это сделано для того, чтобы порядок был детерминированным, что позволяло вычислять хэши и тому подобное.

См. документы.

Вы можете отключить это с помощью параметра JSON_SORT_KEYS.

Если вы хотите отладить часть зефира, просто распечатайте дамп (output) в вашей функции просмотра.

Если у вас нет веской причины форсировать порядок вывода, вам, вероятно, лучше просто отпустить его.

Примечание. В flask-smorest я не возражаю против упорядочивания полезной нагрузки в ответах в алфавитном порядке, но мне нравится, что она упорядочена при публикации файла спецификации OpenAPI, поэтому я не изменяю JSON_SORT_KEYS и в ресурсе, обслуживающем спецификацию файл, IOREFERFOLLOW " используйте jsonify, но необработанные файлы json.dumps.

1
Jérôme 23 Фев 2021 в 09:22