Bug: handle_constrained_decimal not enforcing SQL numeric type precision properly #634
Open
1 of 4 tasks
Labels
bug
Something isn't working
Description
When using the
SQLAlchemyFactory
, constraints onNumeric
columns are not applied correctly.The PostgreSQL documentation defines the following for the
Numeric
type:In our project we create a SQLAlchemy model with a bunch of columns, including a few
Numeric
columns. For one of these, we require the column to have at most 4 digits, and two decimals. Effectively, we're stating that the value should be between a float such that(0, 100)
holds, translating into the following DDL:Since the
Numeric
type doesn't allow specifying greater than or less than values, we expect this constraint would translate to the factory, accurately following the spec. While the numeric precision and digits translate to the correctConstraint
, thatConstraint
isn't applied accurately forSQLAlchemyFactory
factories:max_digits
(which is mapped toprecision
) is applied only to the part before the decimal point.I believe the issue is that a
Decimal
is first created inhandle_constrained_decimal
before checking if the constraints hold. Therefore, we can end up withDecimal
s that are outside of theNumeric
constraints that we expect based on the SQL spec.A workaround that I currently employed in our codebase is that for the explicit fields where this is causing flaky behavior, I manually set a minimum and maximum value so that the generated
Decimal
is correct. However, sinceNumeric
doesn't allow specifying greater or lesser than values, this leads to increased overhead.Please see below working example.
URL to code causing the issue
No response
MCVE
This will in most cases print out at least a few floats that are greater than the constraints specify:
Steps to reproduce
The above example is self-contained and can be run as-is, e.g. in a Jupyter notebook.
Screenshots
No response
Logs
Release Version
polyfactory==2.18.1
python==3.12.3
Platform
The text was updated successfully, but these errors were encountered: