Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Types: Add support for BINARY columns and improve support for FLOATs #12

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/sqlalchemy_cratedb/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@
"they will be omitted when generating DDL statements.")
return None

def visit_create_index(self, create, **kw):
return "SELECT 1;"

Check warning on line 201 in src/sqlalchemy_cratedb/compiler.py

View check run for this annotation

Codecov / codecov/patch

src/sqlalchemy_cratedb/compiler.py#L201

Added line #L201 was not covered by tests


class CrateTypeCompiler(compiler.GenericTypeCompiler):

Expand Down Expand Up @@ -255,6 +258,30 @@
(type_.timezone and "WITH" or "WITHOUT") + " TIME ZONE",
)

def visit_BLOB(self, type_, **kw):
return "STRING"

Check warning on line 262 in src/sqlalchemy_cratedb/compiler.py

View check run for this annotation

Codecov / codecov/patch

src/sqlalchemy_cratedb/compiler.py#L262

Added line #L262 was not covered by tests

def visit_FLOAT(self, type_, **kw):
"""
From `sqlalchemy.sql.sqltypes.Float`.

When a :paramref:`.Float.precision` is not provided in a
:class:`_types.Float` type some backend may compile this type as
an 8 bytes / 64 bit float datatype. To use a 4 bytes / 32 bit float
datatype a precision <= 24 can usually be provided or the
:class:`_types.REAL` type can be used.
This is known to be the case in the PostgreSQL and MSSQL dialects
that render the type as ``FLOAT`` that's in both an alias of
``DOUBLE PRECISION``. Other third party dialects may have similar
behavior.
"""
if not type_.precision:
return "FLOAT"
elif type_.precision <= 24:
return "FLOAT"

Check warning on line 281 in src/sqlalchemy_cratedb/compiler.py

View check run for this annotation

Codecov / codecov/patch

src/sqlalchemy_cratedb/compiler.py#L281

Added line #L281 was not covered by tests
else:
return "DOUBLE"


class CrateCompiler(compiler.SQLCompiler):

Expand Down
2 changes: 2 additions & 0 deletions src/sqlalchemy_cratedb/dialect.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
)
from .sa_version import SA_VERSION, SA_1_4, SA_2_0
from .type import FloatVector, ObjectArray, ObjectType
from .type.binary import LargeBinary

TYPES_MAP = {
"boolean": sqltypes.Boolean,
Expand Down Expand Up @@ -149,6 +150,7 @@ def process(value):
sqltypes.Date: Date,
sqltypes.DateTime: DateTime,
sqltypes.TIMESTAMP: DateTime,
sqltypes.LargeBinary: LargeBinary,
}


Expand Down
1 change: 1 addition & 0 deletions src/sqlalchemy_cratedb/type/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .array import ObjectArray
from .binary import LargeBinary
from .geo import Geopoint, Geoshape
from .object import ObjectType
from .vector import FloatVector, knn_match
44 changes: 44 additions & 0 deletions src/sqlalchemy_cratedb/type/binary.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import base64
import sqlalchemy as sa


class LargeBinary(sa.String):

"""A type for large binary byte data.

The :class:`.LargeBinary` type corresponds to a large and/or unlengthed
binary type for the target platform, such as BLOB on MySQL and BYTEA for
PostgreSQL. It also handles the necessary conversions for the DBAPI.

"""

__visit_name__ = "large_binary"

def bind_processor(self, dialect):
if dialect.dbapi is None:
return None

Check warning on line 19 in src/sqlalchemy_cratedb/type/binary.py

View check run for this annotation

Codecov / codecov/patch

src/sqlalchemy_cratedb/type/binary.py#L18-L19

Added lines #L18 - L19 were not covered by tests

# TODO: DBAPIBinary = dialect.dbapi.Binary

def process(value):
if value is not None:

Check warning on line 24 in src/sqlalchemy_cratedb/type/binary.py

View check run for this annotation

Codecov / codecov/patch

src/sqlalchemy_cratedb/type/binary.py#L23-L24

Added lines #L23 - L24 were not covered by tests
# TODO: return DBAPIBinary(value)
return base64.b64encode(value).decode()

Check warning on line 26 in src/sqlalchemy_cratedb/type/binary.py

View check run for this annotation

Codecov / codecov/patch

src/sqlalchemy_cratedb/type/binary.py#L26

Added line #L26 was not covered by tests
else:
return None

Check warning on line 28 in src/sqlalchemy_cratedb/type/binary.py

View check run for this annotation

Codecov / codecov/patch

src/sqlalchemy_cratedb/type/binary.py#L28

Added line #L28 was not covered by tests

return process

Check warning on line 30 in src/sqlalchemy_cratedb/type/binary.py

View check run for this annotation

Codecov / codecov/patch

src/sqlalchemy_cratedb/type/binary.py#L30

Added line #L30 was not covered by tests
Comment on lines +17 to +30
Copy link
Member Author

@amotl amotl Dec 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self, or others who want to pick this up:

Review that detail about returning a DBAPIBinary, or not.


# Python 3 has native bytes() type
# both sqlite3 and pg8000 seem to return it,
# psycopg2 as of 2.5 returns 'memoryview'
def result_processor(self, dialect, coltype):
if dialect.returns_native_bytes:
return None

Check warning on line 37 in src/sqlalchemy_cratedb/type/binary.py

View check run for this annotation

Codecov / codecov/patch

src/sqlalchemy_cratedb/type/binary.py#L36-L37

Added lines #L36 - L37 were not covered by tests

def process(value):
if value is not None:
return base64.b64decode(value)
return value

Check warning on line 42 in src/sqlalchemy_cratedb/type/binary.py

View check run for this annotation

Codecov / codecov/patch

src/sqlalchemy_cratedb/type/binary.py#L39-L42

Added lines #L39 - L42 were not covered by tests

return process

Check warning on line 44 in src/sqlalchemy_cratedb/type/binary.py

View check run for this annotation

Codecov / codecov/patch

src/sqlalchemy_cratedb/type/binary.py#L44

Added line #L44 was not covered by tests
Comment on lines +32 to +44
Copy link
Member Author

@amotl amotl Dec 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self, or others who want to pick this up:

Review that detail about dialect.returns_native_bytes: Should it be handled differently, because, well, base64.b64decode actually returns native bytes already?