Skip to content

Commit

Permalink
Types: Add support for BINARY columns and improve support for FLOATs
Browse files Browse the repository at this point in the history
  • Loading branch information
amotl committed Jun 25, 2024
1 parent 6db4702 commit 73bfe8e
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 0 deletions.
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 @@ def visit_unique_constraint(self, constraint, **kw):
"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 @@ def visit_TIMESTAMP(self, type_, **kw):
(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

# 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

0 comments on commit 73bfe8e

Please sign in to comment.