diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db03237..630f30a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,9 +41,7 @@ jobs: matrix: crdb-version: [ "cockroach:latest-v24.1", - "cockroach:latest-v24.2", "cockroach:latest-v24.3", - "cockroach:latest-v25.1", "cockroach:latest-v25.2", "cockroach:latest-v25.3" ] diff --git a/CHANGES.md b/CHANGES.md index 9a05580..db4594d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,8 @@ # Version 2.0.4 Unreleased +- Fix reflection of CHAR columns (#275) + # Version 2.0.3 June 10, 2025 diff --git a/dev-requirements.txt b/dev-requirements.txt index 2972413..5569de9 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -6,7 +6,7 @@ cffi==1.17.1 # via cryptography charset-normalizer==3.4.3 # via requests -cryptography==45.0.6 +cryptography==45.0.7 # via secretstorage distlib==0.4.0 # via virtualenv @@ -50,7 +50,7 @@ packaging==25.0 # via # tox # twine -platformdirs==4.3.8 +platformdirs==4.4.0 # via virtualenv pluggy==1.6.0 # via tox @@ -85,7 +85,7 @@ tox==3.23.1 # via -r dev-requirements.in twine==6.1.0 # via -r dev-requirements.in -typing-extensions==4.14.1 +typing-extensions==4.15.0 # via virtualenv urllib3==2.5.0 # via diff --git a/sqlalchemy_cockroachdb/base.py b/sqlalchemy_cockroachdb/base.py index 734aab9..efba860 100644 --- a/sqlalchemy_cockroachdb/base.py +++ b/sqlalchemy_cockroachdb/base.py @@ -49,9 +49,9 @@ "timestamp with time zone": sqltypes.TIMESTAMP, "timestamp without time zone": sqltypes.TIMESTAMP, "interval": sqltypes.Interval, - "char": sqltypes.VARCHAR, + "char": sqltypes.CHAR, "char varying": sqltypes.VARCHAR, - "character": sqltypes.VARCHAR, + "character": sqltypes.CHAR, "character varying": sqltypes.VARCHAR, "string": sqltypes.VARCHAR, "text": sqltypes.VARCHAR, @@ -244,7 +244,7 @@ def get_columns(self, conn, table_name, schema=None, **kw): precision=row.numeric_precision, scale=row.numeric_scale, ) - elif type_class is sqltypes.VARCHAR: + elif type_class is sqltypes.VARCHAR or type_class is sqltypes.CHAR: typ = type_class(length=row.character_maximum_length) else: typ = type_class diff --git a/test-requirements.txt b/test-requirements.txt index dccfb12..ea20614 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,4 +1,4 @@ -alembic==1.16.4 +alembic==1.16.5 # via -r test-requirements.in async-timeout==5.0.1 # via asyncpg @@ -40,7 +40,7 @@ tomli==2.2.1 # via # alembic # pytest -typing-extensions==4.14.1 +typing-extensions==4.15.0 # via # alembic # exceptiongroup diff --git a/test/test_introspection.py b/test/test_introspection.py index 21c126c..b7caba8 100644 --- a/test/test_introspection.py +++ b/test/test_introspection.py @@ -136,11 +136,17 @@ def test_timestamp(self): def test_interval(self): self._test("interval", sqltypes.Interval) - def test_varchar(self): + def test_char(self): types = [ "char", - "char varying", "character", + ] + for t in types: + self._test(t, sqltypes.CHAR) + + def test_varchar(self): + types = [ + "char varying", "character varying", "string", "text", diff --git a/test/test_suite_alembic.py b/test/test_suite_alembic.py index 1ee3a88..fbbad02 100644 --- a/test/test_suite_alembic.py +++ b/test/test_suite_alembic.py @@ -1,23 +1,13 @@ from alembic.testing.suite import * # noqa -from sqlalchemy.testing import skip -from alembic.testing.suite import AutogenerateFKOptionsTest as _AutogenerateFKOptionsTest +# from sqlalchemy.testing import skip from alembic.testing.suite import BackendAlterColumnTest as _BackendAlterColumnTest -class AutogenerateFKOptionsTest(_AutogenerateFKOptionsTest): - @skip("cockroachdb") - def test_nochange_ondelete(self): - pass - - class BackendAlterColumnTest(_BackendAlterColumnTest): - @skip("cockroachdb") def test_modify_nullable_to_non(self): - # previously needed "with self.op.get_context().autocommit_block():" - # which is no longer valid in SQLA 2.0 - pass + if config.db.dialect._is_v253plus: + super().test_modify_nullable_to_non() - @skip("cockroachdb") def test_modify_type_int_str(self): - # TODO: enable this test when warning removed for ALTER COLUMN int → string - pass + if config.db.dialect._is_v253plus: + super().test_modify_type_int_str() diff --git a/test/test_suite_sqlalchemy.py b/test/test_suite_sqlalchemy.py index 86976b7..778d6f9 100644 --- a/test/test_suite_sqlalchemy.py +++ b/test/test_suite_sqlalchemy.py @@ -4,9 +4,6 @@ from sqlalchemy.testing.suite import ( ComponentReflectionTest as _ComponentReflectionTest, ) -from sqlalchemy.testing.suite import ( - ComponentReflectionTestExtra as _ComponentReflectionTestExtra, -) from sqlalchemy.testing.suite import HasIndexTest as _HasIndexTest from sqlalchemy.testing.suite import HasTableTest as _HasTableTest from sqlalchemy.testing.suite import IntegerTest as _IntegerTest @@ -21,7 +18,6 @@ ) from sqlalchemy.testing.suite import TrueDivTest as _TrueDivTest from sqlalchemy.testing.suite import UnicodeSchemaTest as _UnicodeSchemaTest -import sqlalchemy.types as sql_types class ComponentReflectionTest(_ComponentReflectionTest): @@ -421,19 +417,6 @@ def test_not_existing_table(self): pass -class ComponentReflectionTestExtra(_ComponentReflectionTestExtra): - @testing.combinations( - sql_types.String, - sql_types.VARCHAR, - # sql_types.CHAR, # we return VARCHAR(length=52) - (sql_types.NVARCHAR, testing.requires.nvarchar_types), - (sql_types.NCHAR, testing.requires.nvarchar_types), - argnames="type_", - ) - def test_string_length_reflection(self, connection, metadata, type_): - super().test_string_length_reflection(connection, metadata, type_, []) - - class HasIndexTest(_HasIndexTest): @skip("cockroachdb") def test_has_index(self):