diff --git a/CHANGES.md b/CHANGES.md index 538c99d..d4ef5d7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,7 @@ 'visit_on_conflict_do_update'` by forwarding calls to `PGCompiler.visit_on_conflict_do_update` - Dialect: Added methods concerned with isolation levels as no-ops +- Types: Started emulating PostgreSQL's `JSON(B)` types using CrateDB's `OBJECT` ## 2026/05/28 0.42.0 - Added support for SQL Alchemy 2.1 diff --git a/docs/data-types.rst b/docs/data-types.rst index 3b03752..da05ae4 100644 --- a/docs/data-types.rst +++ b/docs/data-types.rst @@ -51,6 +51,8 @@ CrateDB SQLAlchemy `string`__ `String`__ `array`__ `ARRAY`__ `object`__ :ref:`object` |nbsp| (extension type) +`object`__ ``JSON`` +`object`__ ``JSONB`` `array(object)`__ :ref:`objectarray` |nbsp| (extension type) `geo_point`__ :ref:`geopoint` |nbsp| (extension type) `geo_shape`__ :ref:`geoshape` |nbsp| (extension type) @@ -79,6 +81,8 @@ __ http://docs.sqlalchemy.org/en/latest/core/type_basics.html#sqlalchemy.types.S __ https://cratedb.com/docs/crate/reference/en/latest/general/ddl/data-types.html#array __ http://docs.sqlalchemy.org/en/latest/core/type_basics.html#sqlalchemy.types.ARRAY __ https://cratedb.com/docs/crate/reference/en/latest/general/ddl/data-types.html#object +__ https://cratedb.com/docs/crate/reference/en/latest/general/ddl/data-types.html#object +__ https://cratedb.com/docs/crate/reference/en/latest/general/ddl/data-types.html#object __ https://cratedb.com/docs/crate/reference/en/latest/general/ddl/data-types.html#array __ https://cratedb.com/docs/crate/reference/en/latest/general/ddl/data-types.html#geo-point __ https://cratedb.com/docs/crate/reference/en/latest/general/ddl/data-types.html#geo-shape diff --git a/src/sqlalchemy_cratedb/compiler.py b/src/sqlalchemy_cratedb/compiler.py index e98dda2..7fffaaf 100644 --- a/src/sqlalchemy_cratedb/compiler.py +++ b/src/sqlalchemy_cratedb/compiler.py @@ -271,6 +271,12 @@ def visit_TIMESTAMP(self, type_, **kw): """ return "TIMESTAMP %s" % ((type_.timezone and "WITH" or "WITHOUT") + " TIME ZONE",) + def visit_JSON(self, type_, **kw): + return "OBJECT" + + def visit_JSONB(self, type_, **kw): + return "OBJECT" + class CrateCompiler(compiler.SQLCompiler): def visit_getitem_binary(self, binary, operator, **kw): diff --git a/tests/compiler_test.py b/tests/compiler_test.py index 853ec47..1b41e6d 100644 --- a/tests/compiler_test.py +++ b/tests/compiler_test.py @@ -543,3 +543,16 @@ class FooBar(Base): "they will be omitted when generating DDL statements.", str(w[-1].message), ) + + def test_ddl_with_json_columns(self): + mytable = sa.Table("json_table", self.metadata, sa.Column("json", sa.JSON)) + self.metadata.create_all(self.engine, tables=[mytable], checkfirst=False) + self.assertEqual( + self.executed_statement, + dedent(""" + CREATE TABLE testdrive.json_table ( + \tjson OBJECT + ) + + """), + ) # noqa: W291, W293