crate / sqlalchemy-cratedb

SQLAlchemy dialect for CrateDB.
https://cratedb.com/docs/sqlalchemy-cratedb/
Apache License 2.0
0 stars 2 forks source link

SQLAlchemy: Investigate whether and how to build upon the `JSON` type implementation #93

Open amotl opened 1 year ago

amotl commented 1 year ago

About

crate/crate-python#559 revealed that the SQLAlchemy implementation for supporting CrateDB's OBJECT type has drawbacks when accessing the attributes of the dictionary facade by key, i.e. indexing into the dictionary using the classical Entity.field["attribute"] notation.

Thoughts

Here, we are trying to outline a possible alternative way of implementing support for that, which may more closely align to PostgreSQL's JSON type support. While CrateDB itself does not provide support for the JSON|JSONB types, the same SQLAlchemy interface could still be leveraged to access CrateDB's OBJECT type in the same spirit. At least, this is what I am assuming for now.

Details

Please inspect SQLAlchemy's sqltypes.JSON type implementation, which is provided as a facade for vendor-specific JSON types, which are currently PostgreSQL, MySQL, SQLite, and Microsoft SQL Server. Each of them has their own specializations, so I think the chance to re-use some code from the generic type variants for implementing CrateDB's OBJECT type might actually be possible.

New interface

The new interface to index operations is based on data casters.

Index operations, i.e. those invoked by calling upon the expression using the Python bracket operator as in some_column['some key'], return an expression object whose type defaults to JSON by default, so that further JSON-oriented instructions may be called upon the result type.

However, it is likely more common that an index operation is expected to return a specific scalar element, such as a string or integer. In order to provide access to these elements in a backend-agnostic way, a series of data casters are provided. [...]

See section »Casting JSON Elements to Other Types« at the SQLAlchemy JSON type documentation.

Code examples

When adhering to the new interface, the same statement would be written slightly different.

Before

sa.select(Character).where(Character.data['x'] == 1)

After

sa.select(Character).where(Character.data['x'].as_integer() == 1)
amotl commented 1 year ago

A bit of progress with crate/crate-python#561.

amotl commented 1 month ago

That patch may include more improvements in this area.