[TD-2125][TD-2173]<feature>python connector
This commit is contained in:
parent
f3aa56aed0
commit
f9c34c9370
|
@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
||||||
|
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name="taos",
|
name="taos",
|
||||||
version="2.0.0",
|
version="2.0.2",
|
||||||
author="Taosdata Inc.",
|
author="Taosdata Inc.",
|
||||||
author_email="support@taosdata.com",
|
author_email="support@taosdata.com",
|
||||||
description="TDengine python client package",
|
description="TDengine python client package",
|
||||||
|
|
|
@ -18,7 +18,7 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
_timestamp_converter = _convert_microsecond_to_datetime
|
_timestamp_converter = _convert_microsecond_to_datetime
|
||||||
|
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::1]))
|
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
||||||
else:
|
else:
|
||||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C bool row to python row
|
"""Function to convert C bool row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C tinyint row to python row
|
"""Function to convert C tinyint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C smallint row to python row
|
"""Function to convert C smallint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::1]]
|
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)]]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C int row to python row
|
"""Function to convert C int row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::1] ]
|
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C bigint row to python row
|
"""Function to convert C bigint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::1] ]
|
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C float row to python row
|
"""Function to convert C float row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::1] ]
|
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C double row to python row
|
"""Function to convert C double row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::1] ]
|
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C binary row to python row
|
"""Function to convert C binary row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::1]]
|
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||||
else:
|
else:
|
||||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||||
|
|
||||||
|
@ -90,9 +90,7 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C nchar row to python row
|
"""Function to convert C nchar row to python row
|
||||||
"""
|
"""
|
||||||
assert(nbytes is not None)
|
assert(nbytes is not None)
|
||||||
|
res=[]
|
||||||
res = []
|
|
||||||
|
|
||||||
for i in range(abs(num_of_rows)):
|
for i in range(abs(num_of_rows)):
|
||||||
try:
|
try:
|
||||||
if num_of_rows >= 0:
|
if num_of_rows >= 0:
|
||||||
|
@ -103,17 +101,49 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
except ValueError:
|
except ValueError:
|
||||||
res.append(None)
|
res.append(None)
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||||
|
"""Function to convert C binary row to python row
|
||||||
|
"""
|
||||||
|
res=[]
|
||||||
|
if num_of_rows > 0:
|
||||||
|
for i in range(abs(num_of_rows)):
|
||||||
|
try:
|
||||||
|
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
||||||
|
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||||
|
res.append( tmpstr.value.decode()[0:rbyte] )
|
||||||
|
except ValueError:
|
||||||
|
res.append(None)
|
||||||
|
else:
|
||||||
|
for i in range(abs(num_of_rows)):
|
||||||
|
try:
|
||||||
|
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
||||||
|
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||||
|
res.append( tmpstr.value.decode()[0:rbyte] )
|
||||||
|
except ValueError:
|
||||||
|
res.append(None)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||||
|
"""Function to convert C nchar row to python row
|
||||||
|
"""
|
||||||
|
assert(nbytes is not None)
|
||||||
|
res=[]
|
||||||
|
if num_of_rows >= 0:
|
||||||
|
for i in range(abs(num_of_rows)):
|
||||||
|
try:
|
||||||
|
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||||
|
res.append( tmpstr.value.decode() )
|
||||||
|
except ValueError:
|
||||||
|
res.append(None)
|
||||||
|
else:
|
||||||
|
for i in range(abs(num_of_rows)):
|
||||||
|
try:
|
||||||
|
res.append( (ctypes.cast(data+nbytes*i+2, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
||||||
|
except ValueError:
|
||||||
|
res.append(None)
|
||||||
return res
|
return res
|
||||||
# if num_of_rows > 0:
|
|
||||||
# for i in range(abs(num_of_rows)):
|
|
||||||
# try:
|
|
||||||
# res.append( (ctypes.cast(data+nbytes*i, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
|
||||||
# except ValueError:
|
|
||||||
# res.append(None)
|
|
||||||
# return res
|
|
||||||
# # return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)][::-1]]
|
|
||||||
# else:
|
|
||||||
# return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)]]
|
|
||||||
|
|
||||||
_CONVERT_FUNC = {
|
_CONVERT_FUNC = {
|
||||||
FieldType.C_BOOL: _crow_bool_to_python,
|
FieldType.C_BOOL: _crow_bool_to_python,
|
||||||
|
@ -128,6 +158,19 @@ _CONVERT_FUNC = {
|
||||||
FieldType.C_NCHAR : _crow_nchar_to_python
|
FieldType.C_NCHAR : _crow_nchar_to_python
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_CONVERT_FUNC_BLOCK = {
|
||||||
|
FieldType.C_BOOL: _crow_bool_to_python,
|
||||||
|
FieldType.C_TINYINT : _crow_tinyint_to_python,
|
||||||
|
FieldType.C_SMALLINT : _crow_smallint_to_python,
|
||||||
|
FieldType.C_INT : _crow_int_to_python,
|
||||||
|
FieldType.C_BIGINT : _crow_bigint_to_python,
|
||||||
|
FieldType.C_FLOAT : _crow_float_to_python,
|
||||||
|
FieldType.C_DOUBLE : _crow_double_to_python,
|
||||||
|
FieldType.C_BINARY: _crow_binary_to_python_block,
|
||||||
|
FieldType.C_TIMESTAMP : _crow_timestamp_to_python,
|
||||||
|
FieldType.C_NCHAR : _crow_nchar_to_python_block
|
||||||
|
}
|
||||||
|
|
||||||
# Corresponding TAOS_FIELD structure in C
|
# Corresponding TAOS_FIELD structure in C
|
||||||
class TaosField(ctypes.Structure):
|
class TaosField(ctypes.Structure):
|
||||||
_fields_ = [('name', ctypes.c_char * 65),
|
_fields_ = [('name', ctypes.c_char * 65),
|
||||||
|
@ -227,8 +270,8 @@ class CTaosInterface(object):
|
||||||
print('connect to TDengine failed')
|
print('connect to TDengine failed')
|
||||||
raise ConnectionError("connect to TDengine failed")
|
raise ConnectionError("connect to TDengine failed")
|
||||||
# sys.exit(1)
|
# sys.exit(1)
|
||||||
else:
|
#else:
|
||||||
print('connect to TDengine success')
|
# print('connect to TDengine success')
|
||||||
|
|
||||||
return connection
|
return connection
|
||||||
|
|
||||||
|
@ -237,7 +280,7 @@ class CTaosInterface(object):
|
||||||
'''Close the TDengine handle
|
'''Close the TDengine handle
|
||||||
'''
|
'''
|
||||||
CTaosInterface.libtaos.taos_close(connection)
|
CTaosInterface.libtaos.taos_close(connection)
|
||||||
print('connection is closed')
|
#print('connection is closed')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def query(connection, sql):
|
def query(connection, sql):
|
||||||
|
@ -310,6 +353,24 @@ class CTaosInterface(object):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def fetchBlock(result, fields):
|
def fetchBlock(result, fields):
|
||||||
|
pblock = ctypes.c_void_p(0)
|
||||||
|
num_of_rows = CTaosInterface.libtaos.taos_fetch_block(
|
||||||
|
result, ctypes.byref(pblock))
|
||||||
|
if num_of_rows == 0:
|
||||||
|
return None, 0
|
||||||
|
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
||||||
|
blocks = [None] * len(fields)
|
||||||
|
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||||
|
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
||||||
|
for i in range(len(fields)):
|
||||||
|
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||||
|
if fields[i]['type'] not in _CONVERT_FUNC_BLOCK:
|
||||||
|
raise DatabaseError("Invalid data type returned from database")
|
||||||
|
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
||||||
|
|
||||||
|
return blocks, abs(num_of_rows)
|
||||||
|
@staticmethod
|
||||||
|
def fetchRow(result, fields):
|
||||||
pblock = ctypes.c_void_p(0)
|
pblock = ctypes.c_void_p(0)
|
||||||
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
||||||
if pblock :
|
if pblock :
|
||||||
|
@ -393,7 +454,7 @@ class CTaosInterface(object):
|
||||||
def errStr(result):
|
def errStr(result):
|
||||||
"""Return the error styring
|
"""Return the error styring
|
||||||
"""
|
"""
|
||||||
return CTaosInterface.libtaos.taos_errstr(result)
|
return CTaosInterface.libtaos.taos_errstr(result).decode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -410,4 +471,4 @@ if __name__ == '__main__':
|
||||||
print(data)
|
print(data)
|
||||||
|
|
||||||
cinter.freeResult(result)
|
cinter.freeResult(result)
|
||||||
cinter.close(conn)
|
cinter.close(conn)
|
||||||
|
|
|
@ -49,7 +49,7 @@ class TDengineCursor(object):
|
||||||
raise OperationalError("Invalid use of fetch iterator")
|
raise OperationalError("Invalid use of fetch iterator")
|
||||||
|
|
||||||
if self._block_rows <= self._block_iter:
|
if self._block_rows <= self._block_iter:
|
||||||
block, self._block_rows = CTaosInterface.fetchBlock(
|
block, self._block_rows = CTaosInterface.fetchRow(
|
||||||
self._result, self._fields)
|
self._result, self._fields)
|
||||||
if self._block_rows == 0:
|
if self._block_rows == 0:
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
@ -190,6 +190,23 @@ class TDengineCursor(object):
|
||||||
if self._result is None or self._fields is None:
|
if self._result is None or self._fields is None:
|
||||||
raise OperationalError("Invalid use of fetchall")
|
raise OperationalError("Invalid use of fetchall")
|
||||||
|
|
||||||
|
buffer = [[] for i in range(len(self._fields))]
|
||||||
|
self._rowcount = 0
|
||||||
|
while True:
|
||||||
|
block, num_of_fields = CTaosInterface.fetchRow(self._result, self._fields)
|
||||||
|
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
||||||
|
if errno != 0:
|
||||||
|
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
|
||||||
|
if num_of_fields == 0:
|
||||||
|
break
|
||||||
|
self._rowcount += num_of_fields
|
||||||
|
for i in range(len(self._fields)):
|
||||||
|
buffer[i].extend(block[i])
|
||||||
|
return list(map(tuple, zip(*buffer)))
|
||||||
|
def fetchall_block(self):
|
||||||
|
if self._result is None or self._fields is None:
|
||||||
|
raise OperationalError("Invalid use of fetchall")
|
||||||
|
|
||||||
buffer = [[] for i in range(len(self._fields))]
|
buffer = [[] for i in range(len(self._fields))]
|
||||||
self._rowcount = 0
|
self._rowcount = 0
|
||||||
while True:
|
while True:
|
||||||
|
@ -203,7 +220,6 @@ class TDengineCursor(object):
|
||||||
for i in range(len(self._fields)):
|
for i in range(len(self._fields)):
|
||||||
buffer[i].extend(block[i])
|
buffer[i].extend(block[i])
|
||||||
return list(map(tuple, zip(*buffer)))
|
return list(map(tuple, zip(*buffer)))
|
||||||
|
|
||||||
def nextset(self):
|
def nextset(self):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
||||||
|
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name="taos",
|
name="taos",
|
||||||
version="2.0.0",
|
version="2.0.2",
|
||||||
author="Taosdata Inc.",
|
author="Taosdata Inc.",
|
||||||
author_email="support@taosdata.com",
|
author_email="support@taosdata.com",
|
||||||
description="TDengine python client package",
|
description="TDengine python client package",
|
||||||
|
|
|
@ -18,7 +18,7 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
_timestamp_converter = _convert_microsecond_to_datetime
|
_timestamp_converter = _convert_microsecond_to_datetime
|
||||||
|
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::1]))
|
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
||||||
else:
|
else:
|
||||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C bool row to python row
|
"""Function to convert C bool row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C tinyint row to python row
|
"""Function to convert C tinyint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C smallint row to python row
|
"""Function to convert C smallint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::1]]
|
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)]]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C int row to python row
|
"""Function to convert C int row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::1] ]
|
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C bigint row to python row
|
"""Function to convert C bigint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::1] ]
|
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C float row to python row
|
"""Function to convert C float row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::1] ]
|
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C double row to python row
|
"""Function to convert C double row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::1] ]
|
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C binary row to python row
|
"""Function to convert C binary row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::1]]
|
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||||
else:
|
else:
|
||||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||||
|
|
||||||
|
@ -90,9 +90,7 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C nchar row to python row
|
"""Function to convert C nchar row to python row
|
||||||
"""
|
"""
|
||||||
assert(nbytes is not None)
|
assert(nbytes is not None)
|
||||||
|
res=[]
|
||||||
res = []
|
|
||||||
|
|
||||||
for i in range(abs(num_of_rows)):
|
for i in range(abs(num_of_rows)):
|
||||||
try:
|
try:
|
||||||
if num_of_rows >= 0:
|
if num_of_rows >= 0:
|
||||||
|
@ -103,17 +101,49 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
except ValueError:
|
except ValueError:
|
||||||
res.append(None)
|
res.append(None)
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||||
|
"""Function to convert C binary row to python row
|
||||||
|
"""
|
||||||
|
res=[]
|
||||||
|
if num_of_rows > 0:
|
||||||
|
for i in range(abs(num_of_rows)):
|
||||||
|
try:
|
||||||
|
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
||||||
|
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||||
|
res.append( tmpstr.value.decode()[0:rbyte] )
|
||||||
|
except ValueError:
|
||||||
|
res.append(None)
|
||||||
|
else:
|
||||||
|
for i in range(abs(num_of_rows)):
|
||||||
|
try:
|
||||||
|
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
||||||
|
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||||
|
res.append( tmpstr.value.decode()[0:rbyte] )
|
||||||
|
except ValueError:
|
||||||
|
res.append(None)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||||
|
"""Function to convert C nchar row to python row
|
||||||
|
"""
|
||||||
|
assert(nbytes is not None)
|
||||||
|
res=[]
|
||||||
|
if num_of_rows >= 0:
|
||||||
|
for i in range(abs(num_of_rows)):
|
||||||
|
try:
|
||||||
|
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||||
|
res.append( tmpstr.value.decode() )
|
||||||
|
except ValueError:
|
||||||
|
res.append(None)
|
||||||
|
else:
|
||||||
|
for i in range(abs(num_of_rows)):
|
||||||
|
try:
|
||||||
|
res.append( (ctypes.cast(data+nbytes*i+2, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
||||||
|
except ValueError:
|
||||||
|
res.append(None)
|
||||||
return res
|
return res
|
||||||
# if num_of_rows > 0:
|
|
||||||
# for i in range(abs(num_of_rows)):
|
|
||||||
# try:
|
|
||||||
# res.append( (ctypes.cast(data+nbytes*i, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
|
||||||
# except ValueError:
|
|
||||||
# res.append(None)
|
|
||||||
# return res
|
|
||||||
# # return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)][::1]]
|
|
||||||
# else:
|
|
||||||
# return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)]]
|
|
||||||
|
|
||||||
_CONVERT_FUNC = {
|
_CONVERT_FUNC = {
|
||||||
FieldType.C_BOOL: _crow_bool_to_python,
|
FieldType.C_BOOL: _crow_bool_to_python,
|
||||||
|
@ -128,6 +158,19 @@ _CONVERT_FUNC = {
|
||||||
FieldType.C_NCHAR : _crow_nchar_to_python
|
FieldType.C_NCHAR : _crow_nchar_to_python
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_CONVERT_FUNC_BLOCK = {
|
||||||
|
FieldType.C_BOOL: _crow_bool_to_python,
|
||||||
|
FieldType.C_TINYINT : _crow_tinyint_to_python,
|
||||||
|
FieldType.C_SMALLINT : _crow_smallint_to_python,
|
||||||
|
FieldType.C_INT : _crow_int_to_python,
|
||||||
|
FieldType.C_BIGINT : _crow_bigint_to_python,
|
||||||
|
FieldType.C_FLOAT : _crow_float_to_python,
|
||||||
|
FieldType.C_DOUBLE : _crow_double_to_python,
|
||||||
|
FieldType.C_BINARY: _crow_binary_to_python_block,
|
||||||
|
FieldType.C_TIMESTAMP : _crow_timestamp_to_python,
|
||||||
|
FieldType.C_NCHAR : _crow_nchar_to_python_block
|
||||||
|
}
|
||||||
|
|
||||||
# Corresponding TAOS_FIELD structure in C
|
# Corresponding TAOS_FIELD structure in C
|
||||||
class TaosField(ctypes.Structure):
|
class TaosField(ctypes.Structure):
|
||||||
_fields_ = [('name', ctypes.c_char * 65),
|
_fields_ = [('name', ctypes.c_char * 65),
|
||||||
|
@ -253,7 +296,7 @@ class CTaosInterface(object):
|
||||||
raise AttributeError("sql is expected as a string")
|
raise AttributeError("sql is expected as a string")
|
||||||
# finally:
|
# finally:
|
||||||
# CTaosInterface.libtaos.close(connection)
|
# CTaosInterface.libtaos.close(connection)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def affectedRows(result):
|
def affectedRows(result):
|
||||||
"""The affected rows after runing query
|
"""The affected rows after runing query
|
||||||
|
@ -308,29 +351,26 @@ class CTaosInterface(object):
|
||||||
|
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
# @staticmethod
|
|
||||||
# def fetchBlock(result, fields):
|
|
||||||
# pblock = ctypes.c_void_p(0)
|
|
||||||
# num_of_rows = CTaosInterface.libtaos.taos_fetch_block(
|
|
||||||
# result, ctypes.byref(pblock))
|
|
||||||
# if num_of_rows == 0:
|
|
||||||
# return None, 0
|
|
||||||
|
|
||||||
# isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
|
||||||
# blocks = [None] * len(fields)
|
|
||||||
# fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
|
||||||
# fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
|
||||||
# for i in range(len(fields)):
|
|
||||||
# data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
|
||||||
|
|
||||||
# if fields[i]['type'] not in _CONVERT_FUNC:
|
|
||||||
# raise DatabaseError("Invalid data type returned from database")
|
|
||||||
# print('====================',fieldLen[i])
|
|
||||||
# blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
|
||||||
|
|
||||||
# return blocks, abs(num_of_rows)
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def fetchBlock(result, fields):
|
def fetchBlock(result, fields):
|
||||||
|
pblock = ctypes.c_void_p(0)
|
||||||
|
num_of_rows = CTaosInterface.libtaos.taos_fetch_block(
|
||||||
|
result, ctypes.byref(pblock))
|
||||||
|
if num_of_rows == 0:
|
||||||
|
return None, 0
|
||||||
|
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
||||||
|
blocks = [None] * len(fields)
|
||||||
|
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||||
|
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
||||||
|
for i in range(len(fields)):
|
||||||
|
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||||
|
if fields[i]['type'] not in _CONVERT_FUNC_BLOCK:
|
||||||
|
raise DatabaseError("Invalid data type returned from database")
|
||||||
|
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
||||||
|
|
||||||
|
return blocks, abs(num_of_rows)
|
||||||
|
@staticmethod
|
||||||
|
def fetchRow(result, fields):
|
||||||
pblock = ctypes.c_void_p(0)
|
pblock = ctypes.c_void_p(0)
|
||||||
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
||||||
if pblock :
|
if pblock :
|
||||||
|
@ -350,6 +390,7 @@ class CTaosInterface(object):
|
||||||
else:
|
else:
|
||||||
return None, 0
|
return None, 0
|
||||||
return blocks, abs(num_of_rows)
|
return blocks, abs(num_of_rows)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def freeResult(result):
|
def freeResult(result):
|
||||||
CTaosInterface.libtaos.taos_free_result(result)
|
CTaosInterface.libtaos.taos_free_result(result)
|
||||||
|
|
|
@ -5,7 +5,6 @@ import threading
|
||||||
|
|
||||||
# querySeqNum = 0
|
# querySeqNum = 0
|
||||||
|
|
||||||
|
|
||||||
class TDengineCursor(object):
|
class TDengineCursor(object):
|
||||||
"""Database cursor which is used to manage the context of a fetch operation.
|
"""Database cursor which is used to manage the context of a fetch operation.
|
||||||
|
|
||||||
|
@ -51,7 +50,7 @@ class TDengineCursor(object):
|
||||||
raise OperationalError("Invalid use of fetch iterator")
|
raise OperationalError("Invalid use of fetch iterator")
|
||||||
|
|
||||||
if self._block_rows <= self._block_iter:
|
if self._block_rows <= self._block_iter:
|
||||||
block, self._block_rows = CTaosInterface.fetchBlock(
|
block, self._block_rows = CTaosInterface.fetchRow(
|
||||||
self._result, self._fields)
|
self._result, self._fields)
|
||||||
if self._block_rows == 0:
|
if self._block_rows == 0:
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
@ -196,18 +195,13 @@ class TDengineCursor(object):
|
||||||
def fetchall(self):
|
def fetchall(self):
|
||||||
"""Fetch all (remaining) rows of a query result, returning them as a sequence of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute can affect the performance of this operation.
|
"""Fetch all (remaining) rows of a query result, returning them as a sequence of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute can affect the performance of this operation.
|
||||||
"""
|
"""
|
||||||
# if threading.get_ident() != self._threadId:
|
|
||||||
# info ="[WARNING] Cursor fetchall:Thread ID not match,creater:"+str(self._threadId)+" caller:"+str(threading.get_ident())
|
|
||||||
# raise OperationalError(info)
|
|
||||||
# print(info)
|
|
||||||
# return None
|
|
||||||
if self._result is None or self._fields is None:
|
if self._result is None or self._fields is None:
|
||||||
raise OperationalError("Invalid use of fetchall")
|
raise OperationalError("Invalid use of fetchall")
|
||||||
|
|
||||||
buffer = [[] for i in range(len(self._fields))]
|
buffer = [[] for i in range(len(self._fields))]
|
||||||
self._rowcount = 0
|
self._rowcount = 0
|
||||||
while True:
|
while True:
|
||||||
block, num_of_fields = CTaosInterface.fetchBlock(self._result, self._fields)
|
block, num_of_fields = CTaosInterface.fetchRow(self._result, self._fields)
|
||||||
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
||||||
if errno != 0:
|
if errno != 0:
|
||||||
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
|
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
|
||||||
|
@ -218,6 +212,22 @@ class TDengineCursor(object):
|
||||||
buffer[i].extend(block[i])
|
buffer[i].extend(block[i])
|
||||||
return list(map(tuple, zip(*buffer)))
|
return list(map(tuple, zip(*buffer)))
|
||||||
|
|
||||||
|
def fetchall_block(self):
|
||||||
|
if self._result is None or self._fields is None:
|
||||||
|
raise OperationalError("Invalid use of fetchall")
|
||||||
|
|
||||||
|
buffer = [[] for i in range(len(self._fields))]
|
||||||
|
self._rowcount = 0
|
||||||
|
while True:
|
||||||
|
block, num_of_fields = CTaosInterface.fetchBlock(self._result, self._fields)
|
||||||
|
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
||||||
|
if errno != 0:
|
||||||
|
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
|
||||||
|
if num_of_fields == 0: break
|
||||||
|
self._rowcount += num_of_fields
|
||||||
|
for i in range(len(self._fields)):
|
||||||
|
buffer[i].extend(block[i])
|
||||||
|
return list(map(tuple, zip(*buffer)))
|
||||||
def nextset(self):
|
def nextset(self):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
||||||
|
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name="taos",
|
name="taos",
|
||||||
version="2.0.0",
|
version="2.0.2",
|
||||||
author="Taosdata Inc.",
|
author="Taosdata Inc.",
|
||||||
author_email="support@taosdata.com",
|
author_email="support@taosdata.com",
|
||||||
description="TDengine python client package",
|
description="TDengine python client package",
|
||||||
|
|
|
@ -18,7 +18,7 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
_timestamp_converter = _convert_microsecond_to_datetime
|
_timestamp_converter = _convert_microsecond_to_datetime
|
||||||
|
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::1]))
|
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)]))
|
||||||
else:
|
else:
|
||||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)]))
|
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)]))
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C bool row to python row
|
"""Function to convert C bool row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C tinyint row to python row
|
"""Function to convert C tinyint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C smallint row to python row
|
"""Function to convert C smallint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::1]]
|
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)]]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C int row to python row
|
"""Function to convert C int row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::1] ]
|
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C bigint row to python row
|
"""Function to convert C bigint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::1] ]
|
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C float row to python row
|
"""Function to convert C float row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::1] ]
|
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C double row to python row
|
"""Function to convert C double row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::1] ]
|
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C binary row to python row
|
"""Function to convert C binary row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::1]]
|
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||||
else:
|
else:
|
||||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||||
|
|
||||||
|
@ -90,9 +90,7 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C nchar row to python row
|
"""Function to convert C nchar row to python row
|
||||||
"""
|
"""
|
||||||
assert(nbytes is not None)
|
assert(nbytes is not None)
|
||||||
|
res=[]
|
||||||
res = []
|
|
||||||
|
|
||||||
for i in range(abs(num_of_rows)):
|
for i in range(abs(num_of_rows)):
|
||||||
try:
|
try:
|
||||||
if num_of_rows >= 0:
|
if num_of_rows >= 0:
|
||||||
|
@ -103,17 +101,49 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
except ValueError:
|
except ValueError:
|
||||||
res.append(None)
|
res.append(None)
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||||
|
"""Function to convert C binary row to python row
|
||||||
|
"""
|
||||||
|
res=[]
|
||||||
|
if num_of_rows > 0:
|
||||||
|
for i in range(abs(num_of_rows)):
|
||||||
|
try:
|
||||||
|
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
||||||
|
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||||
|
res.append( tmpstr.value.decode()[0:rbyte] )
|
||||||
|
except ValueError:
|
||||||
|
res.append(None)
|
||||||
|
else:
|
||||||
|
for i in range(abs(num_of_rows)):
|
||||||
|
try:
|
||||||
|
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
||||||
|
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||||
|
res.append( tmpstr.value.decode()[0:rbyte] )
|
||||||
|
except ValueError:
|
||||||
|
res.append(None)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||||
|
"""Function to convert C nchar row to python row
|
||||||
|
"""
|
||||||
|
assert(nbytes is not None)
|
||||||
|
res=[]
|
||||||
|
if num_of_rows >= 0:
|
||||||
|
for i in range(abs(num_of_rows)):
|
||||||
|
try:
|
||||||
|
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||||
|
res.append( tmpstr.value.decode() )
|
||||||
|
except ValueError:
|
||||||
|
res.append(None)
|
||||||
|
else:
|
||||||
|
for i in range(abs(num_of_rows)):
|
||||||
|
try:
|
||||||
|
res.append( (ctypes.cast(data+nbytes*i+2, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
||||||
|
except ValueError:
|
||||||
|
res.append(None)
|
||||||
return res
|
return res
|
||||||
# if num_of_rows > 0:
|
|
||||||
# for i in range(abs(num_of_rows)):
|
|
||||||
# try:
|
|
||||||
# res.append( (ctypes.cast(data+nbytes*i, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
|
||||||
# except ValueError:
|
|
||||||
# res.append(None)
|
|
||||||
# return res
|
|
||||||
# # return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)][::-1]]
|
|
||||||
# else:
|
|
||||||
# return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)]]
|
|
||||||
|
|
||||||
_CONVERT_FUNC = {
|
_CONVERT_FUNC = {
|
||||||
FieldType.C_BOOL: _crow_bool_to_python,
|
FieldType.C_BOOL: _crow_bool_to_python,
|
||||||
|
@ -128,6 +158,19 @@ _CONVERT_FUNC = {
|
||||||
FieldType.C_NCHAR : _crow_nchar_to_python
|
FieldType.C_NCHAR : _crow_nchar_to_python
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_CONVERT_FUNC_BLOCK = {
|
||||||
|
FieldType.C_BOOL: _crow_bool_to_python,
|
||||||
|
FieldType.C_TINYINT : _crow_tinyint_to_python,
|
||||||
|
FieldType.C_SMALLINT : _crow_smallint_to_python,
|
||||||
|
FieldType.C_INT : _crow_int_to_python,
|
||||||
|
FieldType.C_BIGINT : _crow_bigint_to_python,
|
||||||
|
FieldType.C_FLOAT : _crow_float_to_python,
|
||||||
|
FieldType.C_DOUBLE : _crow_double_to_python,
|
||||||
|
FieldType.C_BINARY: _crow_binary_to_python_block,
|
||||||
|
FieldType.C_TIMESTAMP : _crow_timestamp_to_python,
|
||||||
|
FieldType.C_NCHAR : _crow_nchar_to_python_block
|
||||||
|
}
|
||||||
|
|
||||||
# Corresponding TAOS_FIELD structure in C
|
# Corresponding TAOS_FIELD structure in C
|
||||||
class TaosField(ctypes.Structure):
|
class TaosField(ctypes.Structure):
|
||||||
_fields_ = [('name', ctypes.c_char * 65),
|
_fields_ = [('name', ctypes.c_char * 65),
|
||||||
|
@ -225,9 +268,10 @@ class CTaosInterface(object):
|
||||||
|
|
||||||
if connection.value == None:
|
if connection.value == None:
|
||||||
print('connect to TDengine failed')
|
print('connect to TDengine failed')
|
||||||
|
raise ConnectionError("connect to TDengine failed")
|
||||||
# sys.exit(1)
|
# sys.exit(1)
|
||||||
else:
|
#else:
|
||||||
print('connect to TDengine success')
|
# print('connect to TDengine success')
|
||||||
|
|
||||||
return connection
|
return connection
|
||||||
|
|
||||||
|
@ -236,7 +280,7 @@ class CTaosInterface(object):
|
||||||
'''Close the TDengine handle
|
'''Close the TDengine handle
|
||||||
'''
|
'''
|
||||||
CTaosInterface.libtaos.taos_close(connection)
|
CTaosInterface.libtaos.taos_close(connection)
|
||||||
print('connection is closed')
|
#print('connection is closed')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def query(connection, sql):
|
def query(connection, sql):
|
||||||
|
@ -252,7 +296,7 @@ class CTaosInterface(object):
|
||||||
raise AttributeError("sql is expected as a string")
|
raise AttributeError("sql is expected as a string")
|
||||||
# finally:
|
# finally:
|
||||||
# CTaosInterface.libtaos.close(connection)
|
# CTaosInterface.libtaos.close(connection)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def affectedRows(result):
|
def affectedRows(result):
|
||||||
"""The affected rows after runing query
|
"""The affected rows after runing query
|
||||||
|
@ -309,6 +353,24 @@ class CTaosInterface(object):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def fetchBlock(result, fields):
|
def fetchBlock(result, fields):
|
||||||
|
pblock = ctypes.c_void_p(0)
|
||||||
|
num_of_rows = CTaosInterface.libtaos.taos_fetch_block(
|
||||||
|
result, ctypes.byref(pblock))
|
||||||
|
if num_of_rows == 0:
|
||||||
|
return None, 0
|
||||||
|
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
||||||
|
blocks = [None] * len(fields)
|
||||||
|
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||||
|
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
||||||
|
for i in range(len(fields)):
|
||||||
|
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||||
|
if fields[i]['type'] not in _CONVERT_FUNC_BLOCK:
|
||||||
|
raise DatabaseError("Invalid data type returned from database")
|
||||||
|
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
||||||
|
|
||||||
|
return blocks, abs(num_of_rows)
|
||||||
|
@staticmethod
|
||||||
|
def fetchRow(result, fields):
|
||||||
pblock = ctypes.c_void_p(0)
|
pblock = ctypes.c_void_p(0)
|
||||||
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
||||||
if pblock :
|
if pblock :
|
||||||
|
@ -393,7 +455,7 @@ class CTaosInterface(object):
|
||||||
def errStr(result):
|
def errStr(result):
|
||||||
"""Return the error styring
|
"""Return the error styring
|
||||||
"""
|
"""
|
||||||
return CTaosInterface.libtaos.taos_errstr(result)
|
return CTaosInterface.libtaos.taos_errstr(result).decode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -410,4 +472,4 @@ if __name__ == '__main__':
|
||||||
print(data)
|
print(data)
|
||||||
|
|
||||||
cinter.freeResult(result)
|
cinter.freeResult(result)
|
||||||
cinter.close(conn)
|
cinter.close(conn)
|
||||||
|
|
|
@ -50,7 +50,7 @@ class TDengineCursor(object):
|
||||||
raise OperationalError("Invalid use of fetch iterator")
|
raise OperationalError("Invalid use of fetch iterator")
|
||||||
|
|
||||||
if self._block_rows <= self._block_iter:
|
if self._block_rows <= self._block_iter:
|
||||||
block, self._block_rows = CTaosInterface.fetchBlock(self._result, self._fields)
|
block, self._block_rows = CTaosInterface.fetchRow(self._result, self._fields)
|
||||||
if self._block_rows == 0:
|
if self._block_rows == 0:
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
self._block = list(map(tuple, zip(*block)))
|
self._block = list(map(tuple, zip(*block)))
|
||||||
|
@ -143,7 +143,25 @@ class TDengineCursor(object):
|
||||||
"""
|
"""
|
||||||
if self._result is None or self._fields is None:
|
if self._result is None or self._fields is None:
|
||||||
raise OperationalError("Invalid use of fetchall")
|
raise OperationalError("Invalid use of fetchall")
|
||||||
|
|
||||||
|
buffer = [[] for i in range(len(self._fields))]
|
||||||
|
self._rowcount = 0
|
||||||
|
while True:
|
||||||
|
block, num_of_fields = CTaosInterface.fetchRow(self._result, self._fields)
|
||||||
|
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
||||||
|
if errno != 0:
|
||||||
|
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
|
||||||
|
if num_of_fields == 0:
|
||||||
|
break
|
||||||
|
self._rowcount += num_of_fields
|
||||||
|
for i in range(len(self._fields)):
|
||||||
|
buffer[i].extend(block[i])
|
||||||
|
return list(map(tuple, zip(*buffer)))
|
||||||
|
|
||||||
|
def fetchall_block(self):
|
||||||
|
if self._result is None or self._fields is None:
|
||||||
|
raise OperationalError("Invalid use of fetchall")
|
||||||
|
|
||||||
buffer = [[] for i in range(len(self._fields))]
|
buffer = [[] for i in range(len(self._fields))]
|
||||||
self._rowcount = 0
|
self._rowcount = 0
|
||||||
while True:
|
while True:
|
||||||
|
@ -178,7 +196,7 @@ class TDengineCursor(object):
|
||||||
self._description = None
|
self._description = None
|
||||||
self._rowcount = -1
|
self._rowcount = -1
|
||||||
if self._result is not None:
|
if self._result is not None:
|
||||||
CTaosInterface.freeResult(self._result)
|
CTaosInterface.freeResult(self._result)
|
||||||
self._result = None
|
self._result = None
|
||||||
self._fields = None
|
self._fields = None
|
||||||
self._block = None
|
self._block = None
|
||||||
|
|
|
@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
||||||
|
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name="taos",
|
name="taos",
|
||||||
version="2.0.0",
|
version="2.0.2",
|
||||||
author="Taosdata Inc.",
|
author="Taosdata Inc.",
|
||||||
author_email="support@taosdata.com",
|
author_email="support@taosdata.com",
|
||||||
description="TDengine python client package",
|
description="TDengine python client package",
|
||||||
|
|
|
@ -18,7 +18,7 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
_timestamp_converter = _convert_microsecond_to_datetime
|
_timestamp_converter = _convert_microsecond_to_datetime
|
||||||
|
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::1]))
|
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)]))
|
||||||
else:
|
else:
|
||||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)]))
|
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)]))
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C bool row to python row
|
"""Function to convert C bool row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C tinyint row to python row
|
"""Function to convert C tinyint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C smallint row to python row
|
"""Function to convert C smallint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::1]]
|
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)]]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C int row to python row
|
"""Function to convert C int row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::1] ]
|
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C bigint row to python row
|
"""Function to convert C bigint row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::1] ]
|
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ]
|
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C float row to python row
|
"""Function to convert C float row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::1] ]
|
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C double row to python row
|
"""Function to convert C double row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::1] ]
|
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||||
else:
|
else:
|
||||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
"""Function to convert C binary row to python row
|
"""Function to convert C binary row to python row
|
||||||
"""
|
"""
|
||||||
if num_of_rows > 0:
|
if num_of_rows > 0:
|
||||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::1]]
|
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||||
else:
|
else:
|
||||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||||
|
|
||||||
|
@ -104,16 +104,48 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||||
res.append(None)
|
res.append(None)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
# if num_of_rows > 0:
|
|
||||||
# for i in range(abs(num_of_rows)):
|
def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||||
# try:
|
"""Function to convert C binary row to python row
|
||||||
# res.append( (ctypes.cast(data+nbytes*i, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
"""
|
||||||
# except ValueError:
|
res=[]
|
||||||
# res.append(None)
|
if num_of_rows > 0:
|
||||||
# return res
|
for i in range(abs(num_of_rows)):
|
||||||
# # return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)][::-1]]
|
try:
|
||||||
# else:
|
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
||||||
# return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)]]
|
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||||
|
res.append( tmpstr.value.decode()[0:rbyte] )
|
||||||
|
except ValueError:
|
||||||
|
res.append(None)
|
||||||
|
else:
|
||||||
|
for i in range(abs(num_of_rows)):
|
||||||
|
try:
|
||||||
|
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
||||||
|
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||||
|
res.append( tmpstr.value.decode()[0:rbyte] )
|
||||||
|
except ValueError:
|
||||||
|
res.append(None)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||||
|
"""Function to convert C nchar row to python row
|
||||||
|
"""
|
||||||
|
assert(nbytes is not None)
|
||||||
|
res=[]
|
||||||
|
if num_of_rows >= 0:
|
||||||
|
for i in range(abs(num_of_rows)):
|
||||||
|
try:
|
||||||
|
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||||
|
res.append( tmpstr.value.decode() )
|
||||||
|
except ValueError:
|
||||||
|
res.append(None)
|
||||||
|
else:
|
||||||
|
for i in range(abs(num_of_rows)):
|
||||||
|
try:
|
||||||
|
res.append( (ctypes.cast(data+nbytes*i+2, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
||||||
|
except ValueError:
|
||||||
|
res.append(None)
|
||||||
|
return res
|
||||||
|
|
||||||
_CONVERT_FUNC = {
|
_CONVERT_FUNC = {
|
||||||
FieldType.C_BOOL: _crow_bool_to_python,
|
FieldType.C_BOOL: _crow_bool_to_python,
|
||||||
|
@ -128,6 +160,19 @@ _CONVERT_FUNC = {
|
||||||
FieldType.C_NCHAR : _crow_nchar_to_python
|
FieldType.C_NCHAR : _crow_nchar_to_python
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_CONVERT_FUNC_BLOCK = {
|
||||||
|
FieldType.C_BOOL: _crow_bool_to_python,
|
||||||
|
FieldType.C_TINYINT : _crow_tinyint_to_python,
|
||||||
|
FieldType.C_SMALLINT : _crow_smallint_to_python,
|
||||||
|
FieldType.C_INT : _crow_int_to_python,
|
||||||
|
FieldType.C_BIGINT : _crow_bigint_to_python,
|
||||||
|
FieldType.C_FLOAT : _crow_float_to_python,
|
||||||
|
FieldType.C_DOUBLE : _crow_double_to_python,
|
||||||
|
FieldType.C_BINARY: _crow_binary_to_python_block,
|
||||||
|
FieldType.C_TIMESTAMP : _crow_timestamp_to_python,
|
||||||
|
FieldType.C_NCHAR : _crow_nchar_to_python_block
|
||||||
|
}
|
||||||
|
|
||||||
# Corresponding TAOS_FIELD structure in C
|
# Corresponding TAOS_FIELD structure in C
|
||||||
class TaosField(ctypes.Structure):
|
class TaosField(ctypes.Structure):
|
||||||
_fields_ = [('name', ctypes.c_char * 65),
|
_fields_ = [('name', ctypes.c_char * 65),
|
||||||
|
@ -227,8 +272,8 @@ class CTaosInterface(object):
|
||||||
print('connect to TDengine failed')
|
print('connect to TDengine failed')
|
||||||
raise ConnectionError("connect to TDengine failed")
|
raise ConnectionError("connect to TDengine failed")
|
||||||
# sys.exit(1)
|
# sys.exit(1)
|
||||||
else:
|
#else:
|
||||||
print('connect to TDengine success')
|
# print('connect to TDengine success')
|
||||||
|
|
||||||
return connection
|
return connection
|
||||||
|
|
||||||
|
@ -237,7 +282,7 @@ class CTaosInterface(object):
|
||||||
'''Close the TDengine handle
|
'''Close the TDengine handle
|
||||||
'''
|
'''
|
||||||
CTaosInterface.libtaos.taos_close(connection)
|
CTaosInterface.libtaos.taos_close(connection)
|
||||||
print('connection is closed')
|
#print('connection is closed')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def query(connection, sql):
|
def query(connection, sql):
|
||||||
|
@ -310,6 +355,24 @@ class CTaosInterface(object):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def fetchBlock(result, fields):
|
def fetchBlock(result, fields):
|
||||||
|
pblock = ctypes.c_void_p(0)
|
||||||
|
num_of_rows = CTaosInterface.libtaos.taos_fetch_block(
|
||||||
|
result, ctypes.byref(pblock))
|
||||||
|
if num_of_rows == 0:
|
||||||
|
return None, 0
|
||||||
|
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
||||||
|
blocks = [None] * len(fields)
|
||||||
|
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||||
|
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
||||||
|
for i in range(len(fields)):
|
||||||
|
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||||
|
if fields[i]['type'] not in _CONVERT_FUNC_BLOCK:
|
||||||
|
raise DatabaseError("Invalid data type returned from database")
|
||||||
|
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
||||||
|
|
||||||
|
return blocks, abs(num_of_rows)
|
||||||
|
@staticmethod
|
||||||
|
def fetchRow(result, fields):
|
||||||
pblock = ctypes.c_void_p(0)
|
pblock = ctypes.c_void_p(0)
|
||||||
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
||||||
if pblock :
|
if pblock :
|
||||||
|
|
|
@ -51,7 +51,7 @@ class TDengineCursor(object):
|
||||||
raise OperationalError("Invalid use of fetch iterator")
|
raise OperationalError("Invalid use of fetch iterator")
|
||||||
|
|
||||||
if self._block_rows <= self._block_iter:
|
if self._block_rows <= self._block_iter:
|
||||||
block, self._block_rows = CTaosInterface.fetchBlock(self._result, self._fields)
|
block, self._block_rows = CTaosInterface.fetchRow(self._result, self._fields)
|
||||||
if self._block_rows == 0:
|
if self._block_rows == 0:
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
self._block = list(map(tuple, zip(*block)))
|
self._block = list(map(tuple, zip(*block)))
|
||||||
|
@ -144,7 +144,25 @@ class TDengineCursor(object):
|
||||||
"""
|
"""
|
||||||
if self._result is None or self._fields is None:
|
if self._result is None or self._fields is None:
|
||||||
raise OperationalError("Invalid use of fetchall")
|
raise OperationalError("Invalid use of fetchall")
|
||||||
|
|
||||||
|
buffer = [[] for i in range(len(self._fields))]
|
||||||
|
self._rowcount = 0
|
||||||
|
while True:
|
||||||
|
block, num_of_fields = CTaosInterface.fetchRow(self._result, self._fields)
|
||||||
|
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
||||||
|
if errno != 0:
|
||||||
|
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
|
||||||
|
if num_of_fields == 0:
|
||||||
|
break
|
||||||
|
self._rowcount += num_of_fields
|
||||||
|
for i in range(len(self._fields)):
|
||||||
|
buffer[i].extend(block[i])
|
||||||
|
return list(map(tuple, zip(*buffer)))
|
||||||
|
|
||||||
|
def fetchall_block(self):
|
||||||
|
if self._result is None or self._fields is None:
|
||||||
|
raise OperationalError("Invalid use of fetchall")
|
||||||
|
|
||||||
buffer = [[] for i in range(len(self._fields))]
|
buffer = [[] for i in range(len(self._fields))]
|
||||||
self._rowcount = 0
|
self._rowcount = 0
|
||||||
while True:
|
while True:
|
||||||
|
|
Loading…
Reference in New Issue