BLOB data to string?
I am reading a BLOB column. I can't seem to fetch the data. Searched all over, no luck in finding an answer. I get a java.io stream, how do I handle that?
this print(data[2].getBinaryStream().toString()) results in java.io.ByteArrayInputStream@5d5eef3d
dir(data[2].getBinaryStream().toString()) shows me a toString ['class', 'delattr', 'dict', 'dir', 'doc', 'eq', 'format', 'ge', 'getattribute', 'gt', 'hash', 'init', 'javaclass', 'javaobject', 'le', 'lt', 'metaclass', 'module', 'ne', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'weakref', 'available', 'buf', 'class', 'close', 'count', 'equals', 'getClass', 'hashCode', 'mark', 'markSupported', 'notify', 'notifyAll', 'pos', 'read', 'reset', 'skip', 'toString', 'wait']
dir(data[2]) give me, which is how I found the getBinaryStream function ['class', 'delattr', 'dict', 'dir', 'doc', 'eq', 'format', 'ge', 'getattribute', 'gt', 'hash', 'init', 'javaclass', 'javaobject', 'le', 'lt', 'metaclass', 'module', 'ne', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'weakref', 'a', 'binaryStream', 'c', 'class', 'equals', 'f', 'free', 'g', 'getBinaryStream', 'getBytes', 'getClass', 'h', 'hashCode', 'i', 'j', 'k', 'l', 'length', 'm', 'n', 'notify', 'notifyAll', 'o', 'p', 'position', 'q', 'r', 's', 'setBinaryStream', 'setBytes', 't', 'toString', 'truncate', 'u', 'v', 'w', 'wait', 'x', 'y']
same question...
sql = "select first 1 jiaoym,yuansj from bjybw"
curs.execute(sql)
case = curs.fetchone()
case
[('4661', <jpype._jarray.byte[] object at 0x7fb8d247d2e8>)]
dir(case[1])
['class', 'delattr', 'dict', 'dir', 'doc', 'eq', 'format', 'ge', 'getattribute', 'getitem', 'getslice', 'gt', 'hash', 'init', 'iter', 'javaclass', 'javaobject', 'le', 'len', 'lt', 'module', 'name', 'ne', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr', 'setitem', 'setslice', 'sizeof', 'str', 'subclasshook', 'weakref']
want to get py3 bytearray ...
I'm not an expert in this but had similar issues, using a jTDS driver to access a MS SQL database. Here is how I fixed it:
- Cleanest fix: by adding a parameter useLOBs=false when creating my connection (http://jtds.sourceforge.net/faq.html)
- Before I figured out fix #1 I was doing clob.characterStream.readLine() to read the CLOB object clob
You can edit the _java_to_py function around line 630. the java_val is the object, so you can say getattr(getattr(java_val, "getBinaryStream)(), "toString")() as a way to get data.getBinaryStream().toString() and it should give the expected result.
Create some function like _to_string = _java_to_py("toString") so you can catch it in the if statements of _java_to_py.
Finally you will have to add 'BLOB': _to_string to _DEFAULT_CONVERTERS also if you're editing jaydebeapi.
You can try : curs.execute("select blob from table") data = curs.fetchall() print(data[0][0].stringValue())
This seems to work for blobs for me. I.e. adding:
def _to_binary_stream(rs, col): java_val = rs.getObject(col) if java_val is None: return return getattr(java_val, 'getBinaryStream')()
and then under _DEFAULT_CONVERTERS:
'BLOB': _to_binary_stream
After much searching I landed on:
import jpype
binary_stream = record['blob_column'].getBinaryStream() ByteArray = jpype.JArray(jpype.JByte) j_buffer = ByteArray(1000000) # demonstrate with 1Mb buffer for simplification num_read = int(binary_stream.read(j_buffer)) # Read into buffer and get the length (assuming <1Mb) final_bytes = memoryview(j_buffer[:num_read]).obj
My final implementation leveraged a chunk buffer to read in chunks at a time and a final buffer that is gradually increased each time a chunk needs to be added (lots of copying, but unfortunately the JArray cannot be extended). The binary stream has three methods: read(), read(bytes[]) and read(bytes[], int, int) that reads one character, bytes to fill the provided buffer and bytes to fill the provided buffer from a range in the stream respectively.
you can try this, it works for me, Python3.6, I query data from H2 Embedded and convert blob type to str
def stream2str(s):
"""
org.h2.mvstore.StreamStore$Stream -> str
"""
sl = []
while 1:
try:
sl.append(chr(s.read()))
except ValueError as e:
print(e)
traceback.print_exc()
break
return "".join(sl)
curs.execute("select blob from table")
data = curs.fetchall()
stream = data[0][0].getBinaryStream()
s = stream2str(e)
print(s)