From 9fa79bb53638e02aaa45d77397b39a1b652ba5f1 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 2 Nov 2021 18:19:35 -0400 Subject: [PATCH] map Float to asyncpg.FLOAT, test for infinity Fixes: #7283 Change-Id: I5402a72617b7f9bc366d64bc5ce8669374839984 --- doc/build/changelog/unreleased_14/7283.rst | 9 +++++++++ lib/sqlalchemy/dialects/postgresql/asyncpg.py | 9 +++++++++ lib/sqlalchemy/testing/requirements.py | 6 ++++++ lib/sqlalchemy/testing/suite/test_types.py | 10 ++++++++++ test/requirements.py | 8 ++++++++ 5 files changed, 42 insertions(+) create mode 100644 doc/build/changelog/unreleased_14/7283.rst diff --git a/doc/build/changelog/unreleased_14/7283.rst b/doc/build/changelog/unreleased_14/7283.rst new file mode 100644 index 0000000000..0cfd2a491e --- /dev/null +++ b/doc/build/changelog/unreleased_14/7283.rst @@ -0,0 +1,9 @@ +.. change:: + :tags: bug, postgresql + :tickets: 7283 + + Changed the asyncpg dialect to bind the :class:`.Float` type to the "float" + PostgreSQL type instead of "numeric" so that the value ``float(inf)`` can + be accommodated. Added test suite support for persisence of the "inf" + value. + diff --git a/lib/sqlalchemy/dialects/postgresql/asyncpg.py b/lib/sqlalchemy/dialects/postgresql/asyncpg.py index 3d195e691a..913b931597 100644 --- a/lib/sqlalchemy/dialects/postgresql/asyncpg.py +++ b/lib/sqlalchemy/dialects/postgresql/asyncpg.py @@ -249,6 +249,9 @@ class AsyncpgUUID(UUID): class AsyncpgNumeric(sqltypes.Numeric): + def get_dbapi_type(self, dbapi): + return dbapi.NUMBER + def bind_processor(self, dialect): return None @@ -277,6 +280,11 @@ class AsyncpgNumeric(sqltypes.Numeric): ) +class AsyncpgFloat(AsyncpgNumeric): + def get_dbapi_type(self, dbapi): + return dbapi.FLOAT + + class AsyncpgREGCLASS(REGCLASS): def get_dbapi_type(self, dbapi): return dbapi.STRING @@ -883,6 +891,7 @@ class PGDialect_asyncpg(PGDialect): sqltypes.Integer: AsyncpgInteger, sqltypes.BigInteger: AsyncpgBigInteger, sqltypes.Numeric: AsyncpgNumeric, + sqltypes.Float: AsyncpgFloat, sqltypes.JSON: AsyncpgJSON, json.JSONB: AsyncpgJSONB, sqltypes.JSON.JSONPathType: AsyncpgJSONPathType, diff --git a/lib/sqlalchemy/testing/requirements.py b/lib/sqlalchemy/testing/requirements.py index 8b385b5d2d..08acbd2d2d 100644 --- a/lib/sqlalchemy/testing/requirements.py +++ b/lib/sqlalchemy/testing/requirements.py @@ -980,6 +980,12 @@ class SuiteRequirements(Requirements): return exclusions.closed() + @property + def infinity_floats(self): + """The Float type can persist and load float('inf'), float('-inf').""" + + return exclusions.closed() + @property def precision_generic_float_type(self): """target backend will return native floating point numbers with at diff --git a/lib/sqlalchemy/testing/suite/test_types.py b/lib/sqlalchemy/testing/suite/test_types.py index 93d37d4d50..7438b8bc89 100644 --- a/lib/sqlalchemy/testing/suite/test_types.py +++ b/lib/sqlalchemy/testing/suite/test_types.py @@ -590,6 +590,16 @@ class NumericTest(_LiteralRoundTripFixture, fixtures.TestBase): [15.7563], ) + @testing.requires.infinity_floats + def test_infinity_floats(self, do_numeric_test): + """test for #977, #7283""" + + do_numeric_test( + Float(None), + [float("inf")], + [float("inf")], + ) + @testing.requires.fetch_null_from_numeric def test_numeric_null_as_decimal(self, do_numeric_test): do_numeric_test(Numeric(precision=8, scale=4), [None], [None]) diff --git a/test/requirements.py b/test/requirements.py index 3b77bf6721..134ddbdfa4 100644 --- a/test/requirements.py +++ b/test/requirements.py @@ -1172,6 +1172,14 @@ class DefaultRequirements(SuiteRequirements): ] ) + @property + def infinity_floats(self): + return fails_on_everything_except( + "sqlite", "postgresql+psycopg2", "postgresql+asyncpg" + ) + skip_if( + "postgresql+pg8000", "seems to work on pg14 only, not earlier?" + ) + @property def precision_generic_float_type(self): """target backend will return native floating point numbers with at -- 2.47.2