Skip to content

Commit 7b12867

Browse files
committed
Types: Add support for BLOB type, per base64 encoding
1 parent 435ec4e commit 7b12867

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

src/sqlalchemy_cratedb/compiler.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,9 @@ def visit_TIMESTAMP(self, type_, **kw):
254254
"""
255255
return "TIMESTAMP %s" % ((type_.timezone and "WITH" or "WITHOUT") + " TIME ZONE",)
256256

257+
def visit_BLOB(self, type_, **kw):
258+
return "STRING"
259+
257260

258261
class CrateCompiler(compiler.SQLCompiler):
259262
def visit_getitem_binary(self, binary, operator, **kw):

src/sqlalchemy_cratedb/dialect.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
)
3535
from .sa_version import SA_1_4, SA_2_0, SA_VERSION
3636
from .type import FloatVector, ObjectArray, ObjectType
37+
from .type.binary import LargeBinary
3738

3839
TYPES_MAP = {
3940
"boolean": sqltypes.Boolean,
@@ -158,6 +159,7 @@ def process(value):
158159
sqltypes.Date: Date,
159160
sqltypes.DateTime: DateTime,
160161
sqltypes.TIMESTAMP: DateTime,
162+
sqltypes.LargeBinary: LargeBinary,
161163
}
162164

163165

src/sqlalchemy_cratedb/type/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
from .array import ObjectArray
2+
from .binary import LargeBinary
23
from .geo import Geopoint, Geoshape
34
from .object import ObjectType
45
from .vector import FloatVector, knn_match
56

67
__all__ = [
78
Geopoint,
89
Geoshape,
10+
LargeBinary,
911
ObjectArray,
1012
ObjectType,
1113
FloatVector,

src/sqlalchemy_cratedb/type/binary.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import base64
2+
3+
import sqlalchemy as sa
4+
5+
6+
class LargeBinary(sa.String):
7+
"""A type for large binary byte data.
8+
9+
The :class:`.LargeBinary` type corresponds to a large and/or unlengthed
10+
binary type for the target platform, such as BLOB on MySQL and BYTEA for
11+
PostgreSQL. It also handles the necessary conversions for the DBAPI.
12+
13+
"""
14+
15+
__visit_name__ = "large_binary"
16+
17+
def bind_processor(self, dialect):
18+
if dialect.dbapi is None:
19+
return None
20+
21+
# TODO: DBAPIBinary = dialect.dbapi.Binary
22+
23+
def process(value):
24+
if value is not None:
25+
# TODO: return DBAPIBinary(value)
26+
return base64.b64encode(value).decode()
27+
else:
28+
return None
29+
30+
return process
31+
32+
# Python 3 has native bytes() type
33+
# both sqlite3 and pg8000 seem to return it,
34+
# psycopg2 as of 2.5 returns 'memoryview'
35+
def result_processor(self, dialect, coltype):
36+
if dialect.returns_native_bytes:
37+
return None
38+
39+
def process(value):
40+
if value is not None:
41+
return base64.b64decode(value)
42+
return value
43+
44+
return process

0 commit comments

Comments
 (0)