Flask sqlAlchemy 与 Flask_Marshmallow 的验证问题

2024-01-11

使用flask_marshmallow进行输入验证,并使用scheme.load(),我无法捕获模型中@validates装饰器生成的错误

我捕获了资源中的结果和错误,但错误会直接发送给用户

==========模型.py==========

```python

from sqlalchemy.orm import validates

from sqlalchemy import Column, ForeignKey, Integer, String, DateTime
from sqlalchemy.orm import relationship, backref
from sqlalchemy import create_engine
from sqlalchemy.sql import func

from flask_marshmallow import Marshmallow
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
from sqlalchemy.orm import joinedload


db = SQLAlchemy()
ma = Marshmallow()

class Company(db.Model):

    __tablename__ = "company"

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(250), nullable=False)
    addressLine1 = db.Column(db.String(250), nullable=False)
    addressLine2 = db.Column(db.String(250), nullable=True)
    city = db.Column(db.String(250), nullable=False)
    state = db.Column(db.String(250), nullable=False)
    zipCode = db.Column(db.String(10), nullable=False)
    logo = db.Column(db.String(250), nullable=True)
    website = db.Column(db.String(250), nullable=False)
    recognition = db.Column(db.String(250), nullable=True)
    vision = db.Column(db.String(250), nullable=True)
    history = db.Column(db.String(250), nullable=True)
    mission = db.Column(db.String(250), nullable=True)
    jobs = relationship("Job", cascade="all, delete-orphan")

    def save_to_db(self):
        db.session.add(self)
        db.session.commit()

    @validates('name')
    def validate_name(self, key, name):
        print("=====inside validate_name=======")
        if not name:
            raise AssertionError('No Company name provided')

        if Company.query.filter(Company.name == name).first():
            raise AssertionError('Company name is already in use')

        if len(name) < 4 or len(name) > 120:
            raise AssertionError('Company  name must be between 3 and 120 characters')

        return name

```

==========schemas_company.py==============

```python
from ma import ma
from models.model import Company


class CompanySchema(ma.ModelSchema):

    class Meta:
        model = Company
```

=============resources_company.py

```python
from schemas.company import CompanySchema
company_schema = CompanySchema(exclude='jobs')


COMPANY_ALREADY_EXIST = "A company with the same name already exists"
COMPANY_CREATED_SUCCESSFULLY = "The company was sucessfully created"


@api.route('/company')
class Company(Resource):

    def post(self, *args, **kwargs):
        """ Creating a new Company """
        data = request.get_json(force=True)
        schema = CompanySchema()
        if data:
            logger.info("Data got by /api/test/testId methd %s" % data)


            # Validation with schema.load() OPTION_2
            company, errors = schema.load(data)
            print(company)
            print(errors)

            if errors:
                return {"errors": errors}, 422
            company.save_to_db()
            return {"message": COMPANY_CREATED_SUCCESSFULLY}, 201

```

===========请求==========

这是来自用户的 POST 请求

{
    "name": "123",
    "addressLine1": "400 S Royal King Ave",
    "addressLine2": "Suite 356",
    "city": "Miami",
    "state": "FL",
    "zipCode": "88377",
    "logo": "This is the logo",
    "website": "http://www.python.com",
    "recognition": "Most innovated company in the USA 2018-2019",
    "vision": "We want to change for better all that needs to be changed",
    "history": "Created in 2016 with the objective of automate all needed process",
    "mission": " Our mission is to find solutions to old problems"
}

====问题描述======

上述 POST 请求根据 model.py 中的 validate_name 函数生成 AssertionError 异常,如下所示:

File "code/models/model.py", line 95, in validate_name
raise AssertionError('Company  name must be between 3 and 120 characters')
AssertionError: Company  name must be between 3 and 120 characters
127.0.0.1 - - [30/Dec/2018 13:44:58] "POST /api/company HTTP/1.1" 500 -

所以返回给用户的响应是这个无用的错误消息

{
    "message": "Internal Server Error"
}

我的问题是:

我必须做什么才能将引发的 AssertionError 消息发送给用户而不是这个丑陋的错误消息?

AssertionError message
{
   "message": "Company  name must be between 3 and 120 characters" 
}

Exception 
{
    "message": "Internal Server Error"
}

我认为该错误会捕获 @validates('name') 生成的异常,但看起来并非如此。


我找到了解决问题的方法。 我更改了架构,如下所示:

from ma import ma
from models.model import Company

from marshmallow import fields, validate


class CompanySchema(ma.ModelSchema):

    name = fields.Str(required=True, validate=[validate.Length(min=4, max=250)])
    addressLine1 = fields.Str(required=True, validate=[validate.Length(min=5, max=250)])
    addressLine2 = fields.Str(required=False, validate=[validate.Length(max=250)])
    city = fields.Str(required=True, validate=[validate.Length(min=5, max=100)])
    state = fields.Str(required=True, validate=[validate.Length(min=2, max=10)])
    zipCode = fields.Str(required=True, validate=[validate.Length(min=5, max=250)])
    logo = fields.Str(required=False, validate=[validate.Length(max=250)])
    website = fields.Str(required=True, validate=[validate.Length(min=5, max=250)])
    recognition = fields.Str(required=False, validate=[validate.Length(max=250)])
    vision = fields.Str(required=False, validate=[validate.Length(max=250)])
    history = fields.Str(required=False, validate=[validate.Length(max=250)])
    mission = fields.Str(required=False, validate=[validate.Length(max=250)])

    class Meta:
        model = Company

现在我不验证模型中的任何内容,所以我的模型只是

class Company(db.Model):

    __tablename__ = "company"

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(250), nullable=False)
    addressLine1 = db.Column(db.String(250), nullable=False)
    addressLine2 = db.Column(db.String(250), nullable=True)
    city = db.Column(db.String(250), nullable=False)
    state = db.Column(db.String(250), nullable=False)
    zipCode = db.Column(db.String(10), nullable=False)
    logo = db.Column(db.String(250), nullable=True)
    website = db.Column(db.String(250), nullable=False)
    recognition = db.Column(db.String(250), nullable=True)
    vision = db.Column(db.String(250), nullable=True)
    history = db.Column(db.String(250), nullable=True)
    mission = db.Column(db.String(250), nullable=True)
    jobs = relationship("Job", cascade="all, delete-orphan")

    def save_to_db(self):
        print("=====inside save_to_db=======")
        db.session.add(self)
        db.session.commit()

所以在资源(视图)端点中,我有:

@api.route('/company')
class Company(Resource):

    def post(self, *args, **kwargs):
        """ Creating a new Company """
        data = request.get_json(force=True)
        schema = CompanySchema()
        if data:
            logger.info("Data got by /api/test/testId method %s" % data)

            # Validation with schema.load() OPTION_2
            company, errors = schema.load(data)
            print(company)

            if errors:
                return {"errors": errors}, 422

            company.save_to_db()
            return {"message": COMPANY_CREATED_SUCCESSFULLY}, 201

因此,现在当用户发出名称长度小于 4 个字符的错误请求时,我可以向用户返回一个漂亮的错误响应,如下所示

{
    "errors": {
        "name": [
            "Length must be between 4 and 250."
        ]
    }
}

但如果您注意到我这样做的原因以及我使用的“模式”,您将看到以下详细信息

  1. -使用flask_marshmallow进行序列化和反序列化。
  2. -在我的模型中,我使用棉花糖(不是flask_marshmallow)进行验证
  3. -验证与 schema.load() 一起使用
  4. -我想知道如何向输入添加比我使用的验证更复杂的验证?
  5. -这是一个值得遵循的好模式吗?可以做哪些改进?

Thanks

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Flask sqlAlchemy 与 Flask_Marshmallow 的验证问题 的相关文章

  • 与区域指示符字符类匹配的 python 正则表达式

    我在 Mac 上使用 python 2 7 10 表情符号中的标志由一对表示区域指示符号 https en wikipedia org wiki Regional Indicator Symbol 我想编写一个 python 正则表达式来在
  • 元组有什么用?

    我现在正在学习 Python 课程 我们刚刚介绍了元组作为数据类型之一 我阅读了它的维基百科页面 但是 我无法弄清楚这种数据类型在实践中会有什么用处 我可以提供一些需要一组不可变数字的示例吗 也许是在 Python 中 这与列表有何不同 每
  • 在 django ORM 中查询时如何将 char 转换为整数?

    最近开始使用 Django ORM 我想执行这个查询 select student id from students where student id like 97318 order by CAST student id as UNSIG
  • 将html数据解析成python列表进行操作

    我正在尝试读取 html 网站并提取其数据 例如 我想查看公司过去 5 年的 EPS 每股收益 基本上 我可以读入它 并且可以使用 BeautifulSoup 或 html2text 创建一个巨大的文本块 然后我想搜索该文件 我一直在使用
  • 用枢轴点拟合曲线 Python

    我有下面的图 我想用 2 条线来拟合它 使用 python 我设法适应上半部分 def func x a b x np array x return a x b popt pcov curve fit func up x up y 我想用另
  • 删除flask中的一对一关系

    我目前正在使用 Flask 开发一个应用程序 并且在删除一对一关系中的项目时遇到了一个大问题 我的模型中有以下结构 class User db Model tablename user user id db Column db String
  • 独立滚动矩阵的行

    我有一个矩阵 准确地说 是 2d numpy ndarray A np array 4 0 0 1 2 3 0 0 5 我想滚动每一行A根据另一个数组中的滚动值独立地 r np array 2 0 1 也就是说 我想这样做 print np
  • datetime.datetime.now() 返回旧值

    我正在通过匹配日期查找 python 中的数据存储条目 我想要的是每天选择 今天 的条目 但由于某种原因 当我将代码上传到 gae 服务器时 它只能工作一天 第二天它仍然返回相同的值 例如当我上传代码并在 07 01 2014 执行它时 它
  • 如何在 Python 中解析和比较 ISO 8601 持续时间? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个 Python v2 库 它允许我解析和比较 ISO 8601 持续时间may处于不同单
  • 从Python中的字典列表中查找特定值

    我的字典列表中有以下数据 data I versicolor 0 Sepal Length 7 9 I setosa 0 I virginica 1 I versicolor 0 I setosa 1 I virginica 0 Sepal
  • 在Python中检索PostgreSQL数据库的新记录

    在数据库表中 第二列和第三列有数字 将会不断添加新行 每次 每当数据库表中添加新行时 python 都需要不断检查它们 当 sql 表中收到的新行数低于 105 时 python 应打印一条通知消息 警告 数量已降至 105 以下 另一方面
  • 如何使用 Mysql Python 连接器检索二进制数据?

    如果我在 MySQL 中创建一个包含二进制数据的简单表 CREATE TABLE foo bar binary 4 INSERT INTO foo bar VALUES UNHEX de12 然后尝试使用 MySQL Connector P
  • 如何通过索引列表从 dask 数据框中选择数据?

    我想根据索引列表从 dask 数据框中选择行 我怎样才能做到这一点 Example 假设我有以下 dask 数据框 dict A 1 2 3 4 5 6 7 B 2 3 4 5 6 7 8 index x1 a2 x3 c4 x5 y6 x
  • 如何断言 Unittest 上的可迭代对象不为空?

    向服务提交查询后 我会收到一本字典或一个列表 我想确保它不为空 我使用Python 2 7 我很惊讶没有任何assertEmpty方法为unittest TestCase类实例 现有的替代方案看起来并不正确 self assertTrue
  • 如何解决 PDFBox 没有 unicode 映射错误?

    我有一个现有的 PDF 文件 我想使用 python 脚本将其转换为 Excel 文件 目前正在使用PDFBox 但是存在多个类似以下错误 org apache pdfbox pdmodel font PDType0Font toUnico
  • python import inside函数隐藏现有变量

    我在我正在处理的多子模块项目中遇到了一个奇怪的 UnboundLocalError 分配之前引用的局部变量 问题 并将其精简为这个片段 使用标准库中的日志记录模块 import logging def foo logging info fo
  • 将 Python 中的日期与日期时间进行比较

    所以我有一个日期列表 datetime date 2013 7 9 datetime date 2013 7 12 datetime date 2013 7 15 datetime date 2013 7 18 datetime date
  • 模拟pytest中的异常终止

    我的多线程应用程序遇到了一个错误 主线程的任何异常终止 例如 未捕获的异常或某些信号 都会导致其他线程之一死锁 并阻止进程干净退出 我解决了这个问题 但我想添加一个测试来防止回归 但是 我不知道如何在 pytest 中模拟异常终止 如果我只
  • 如何计算Python中字典中最常见的前10个值

    我对 python 和一般编程都很陌生 所以请友善 我正在尝试分析包含音乐信息的 csv 文件并返回最常听的前 n 个乐队 从下面的代码中 每听一首歌曲都是一个列表中的字典条目 格式如下 album Exile on Main Street
  • 在 JavaScript 函数的 Django 模板中转义字符串参数

    我有一个 JavaScript 函数 它返回一组对象 return Func id name 例如 我在传递包含引号的字符串时遇到问题 Dr Seuss ABC BOOk 是无效语法 I tried name safe 但无济于事 有什么解

随机推荐

  • Python:pandas:将行值与列名/键值匹配

    Problem 如何将行值与列名匹配并在 pandas 中获取该相交值 Context我们有一个像这样的 pandas df df pd DataFrame name john john 1 mac 10 name mac john 2 m
  • 如何使用cakephp在另一个视图中调用视图

    我只是新的 CakePhp 我想知道如何在另一个视图中调用视图 当我开始运行 CakePhp 时 默认布局位于视图 布局 default ctp In 默认 ctp我将视图名称称为 homeview 查看 homes homeview ct
  • 内部样式表在 IE9 中无法与 jsf 一起工作

    我正在使用 jsf2 0 和 primefaces 我的应用程序在包括 IE8 在内的所有浏览器上运行良好 但是当我在 IE9 中运行我的应用程序时 我的内部样式表甚至没有被浏览器 IE9 采用 样式被破坏了 我头上的CSS
  • Gson根据字段名自定义反序列化逻辑

    我的课是这样的 class Foo public String duration public String height 我的 json 数据看起来像 duration 12200000 height 162 现在我想反序列化它 Foo
  • MVC4 WebAPI 的正确架构是什么

    我进行了一些搜索 但没有找到此问题的可用答案 好吧 我的MVC 3架构是这样的 Project EDM contains only the entity framework edmx file and its tt and cs entit
  • 如何使用curl进行POST而不收到HTTP错误422“无法处理的实体”?

    我正在尝试向登录端点发送 POST 请求 我不断收到 HTTP 错误422 Unprocessable Entity 我该如何克服这个错误 以下是我尝试过的一些命令示例 curl v X POST F user email email pr
  • 没有足够的权限访问 S3 中的数据

    我正在关注以下教程入门 控制台 Amazon Personalize https docs aws amazon com personalize latest dg getting started console htmlAmazon Sa
  • 在 angularJS select 指令中设置所选项目

    我在 Angular 的 select 指令中设置所选项目时遇到问题 我不知道这是一个bug还是Angular的设计者有意识的设计 但它确实使 select 指令的用处大大降低 描述 我的应用程序与 REST API 通信以从数据库接收实体
  • 我可以只向某些人分发我的 iPhone 应用程序吗?

    我想开发一个只有我的客户才能使用的特定应用程序 如何限制该应用程序只能由我认可的人下载 Thanks 通过应用程序商店正常分发应用程序 并需要解锁密钥才能运行它 仅将解锁密钥分发给 批准的 用户
  • 升级到 Spring 3.2 后出现 HttpMediaTypeNotAcceptableException

    将 Spring MVC 应用程序升级到 Spring 3 2 后 在访问某些 URL 时出现以下异常 org springframework web HttpMediaTypeNotAcceptableException Could no
  • 暂停 android 下载管理器

    在我的应用程序中 我从服务器下载电影 其中一些非常大 4GB 或更大 我尝试将自己的下载管理器实现为一项服务 但效果并不好 在某些设备上 应用程序会在没有任何通知的情况下自行崩溃 总体而言下载速度似乎太慢 所以 我想使用 Android 的
  • 反序列化对象时出错

    我有一个 JSON 字符串 target FDOL00001 datapoints y 72 564 x 1523858700 target FDOL00001 datapoints y 86 366 x 1523858700 target
  • 在 PHP 中将十六进制颜色转换为 RGB 值

    转换十六进制颜色值的好方法是什么 ffffff转换为单个 RGB 值255 255 255使用 PHP 如果你想将十六进制转换为RGB 你可以使用sscanf https www php net manual en function ssc
  • PHP 服务器端打印

    我过去几个小时一直在谷歌搜索 似乎找不到答案 我确实接近了这个问题 https stackoverflow com questions 1648399 starting serverside print job via php 我的 Win
  • 带单行的 Mercurial 日志

    常规的hg log命令给出每个变更集至少有 4 行的输出 例如 changeset 238 03a214f2a1cf user My Name lt email protected cdn cgi l email protection gt
  • 在联系页面添加地址簿

    我想在我的地址簿中添加contact页面 我想以编程方式执行此操作i e不使用nib files 谁能给我推荐一个不错的教程或示例代码 我已经使用了 iPatel 给出的答案的代码 当我运行时它抛出异常并且应用程序正在终止 感谢致敬 这是编
  • 从 MySQL 中提取所有 JSON 键

    我有一个 JSON 列属性 例如 a 2 b 5 c 3 a 5 d 1 c 7 e 1 f 7 如何从 MySQL 获取所有不同的 顶级 键名 像这样 a b c d e f 谢谢你 测试表 id json col 2 a 2 b 5 3
  • 从毫秒计算周数、天数和小时数

    周围有很多类似的问题 但没有一个解决这个计算 使用 javascript i 很容易找到 ex 的黑白 2 个日期的毫秒数 var mil Math floor new Date 1 1 2012 new Date 1 7 2012 mil
  • OnItemClick 侦听器和单击的视图项的可见性

    我有一个 ListView 其中每个项目都包含一个Textview and ImageView其中imageView is invisible通过单击每个列表视图项目 它将visible我的代码是 Override public void
  • Flask sqlAlchemy 与 Flask_Marshmallow 的验证问题

    使用flask marshmallow进行输入验证 并使用scheme load 我无法捕获模型中 validates装饰器生成的错误 我捕获了资源中的结果和错误 但错误会直接发送给用户 模型 py python from sqlalche