Skip to content

Random Exception between Integrity Error and FlushError #4662

@ghost

Description

Unittest an API, where test code fixture is trying to create a resource and then get the response to verify the previous step, and then again to try to create the same resource again, SqlAlchemy is randomizing the exception between Integrity and Flush Error.

Libs:
Flask==1.0.2
Flask-Cors==3.0.6
Flask-SQLAlchemy==2.3.2
SQLAlchemy==1.2.7
Werkzeug==0.14.1

I have been working on that project for the last 10 month, all the time I have seen only Integrity error, not flush error.

        new_item.before_created(request_data)
        db.session.add(new_item)
        new_item.after_created(request_data)
        db.session.commit()

        headers = {'Location': new_item.get_url()} if new_item.get_url() else None
        return (jsonify({}), 201, headers) if headers else (jsonify({}), 201)
    except KeyError as e:
        raise ValidationError(
            ErrorCode.MISSING_MANDATORY_DATA,
            error_msg=f"the {e.args[0]} field is required.",
        )
    except ValueError as e:
        raise ValidationError(ErrorCode.INVALID_REQUEST_DATA, error_msg=e.args[0])
    except BadRequest:
        raise ValidationError(ErrorCode.INVALID_REQUEST_FORMAT)
    except IntegrityError:
        raise ValidationError(ErrorCode.INTEGRITY_ERROR, status_code=409)
    except Conflict as e:
        raise ValidationError(e.description, status_code=409)
    finally:
        db.session.rollback()

TEST CODE:

    def test_create_new_product(self):
          Product.delete(self.product_no, True)

    # create a asset with the request data.
    response = self.client.post(
        "/assets/",
        content_type="application/json",
        data=json.dumps(self.default_req_data),
    )
    res_data = json.loads(response.data.decode())
    self.assertEqual({}, res_data)
    self.assertEqual(response.status_code, 201)

    # check the asset that we already created.
    response = self.client.get(
        "/assets/{0}".format(self.product_no), content_type="application/json"
    )
    res_data = json.loads(response.data.decode())
    self.assertEqual(response.status_code, 200)

    for key in self.default_req_data.keys():
        self.assertEqual(self.default_req_data[key], res_data[key])

    # try create duplicated asset
    response = self.client.post(
        "/assets/",
        content_type="application/json",
        data=json.dumps(self.default_req_data),
    )
    res_data = json.loads(response.data.decode())
    self.assertEqual(response.status_code, 409)

This fixture is called by several other fixtures but all them get Integrity error except one of them is getting flushError.

If I run all the test together I am facing this issue, alone it works fine.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ormuse casenot really a feature or a bug; can be support for new DB features or user use cases not anticipated

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions