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

Enh/cython #229

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
3914fd5
perf: using cython
hadrianl Aug 17, 2023
b781232
perf: using cython
hadrianl Aug 17, 2023
0ba2600
perf: using cython
hadrianl Aug 17, 2023
40e9cc3
perf: using cython
hadrianl Aug 21, 2023
d1c8db7
perf: using cython
hadrianl Aug 22, 2023
e819e7c
perf: using cython
hadrianl Aug 25, 2023
49cb853
remove c/c++ file
hadrianl Aug 25, 2023
e646ba3
remove temp file
hadrianl Aug 25, 2023
bafaa6e
modify .gitignore
hadrianl Aug 25, 2023
b540257
perf: using cython
hadrianl Aug 28, 2023
4ab9f51
fix cursor execute
hadrianl Aug 28, 2023
9fe89a3
perf: using cython
hadrianl Aug 29, 2023
66a42c0
perf: using cython
hadrianl Aug 29, 2023
6bdeb4b
perf: using cython
hadrianl Aug 29, 2023
68bf344
perf: using cython
hadrianl Sep 4, 2023
6889fdc
perf: using cython
hadrianl Sep 5, 2023
8c371fb
perf: using cython
hadrianl Sep 5, 2023
b108305
perf: using cython
hadrianl Sep 6, 2023
6e739e8
perf: using cython
hadrianl Sep 6, 2023
17fd1c3
perf: using cython
hadrianl Sep 6, 2023
a03bf80
perf: using cython
hadrianl Sep 7, 2023
20989b2
perf: using cython
hadrianl Sep 8, 2023
bdad5f7
perf: using cython
hadrianl Sep 8, 2023
1ab7372
perf: using cython
hadrianl Sep 12, 2023
8abfdfc
perf: using cython
hadrianl Sep 12, 2023
add9a1a
perf: using cython
hadrianl Sep 12, 2023
1c1a75e
perf: using cython
hadrianl Sep 13, 2023
49bbc53
perf: using cython
hadrianl Sep 13, 2023
96e8c4c
perf: using cython
hadrianl Sep 14, 2023
e18ee6a
perf: using cython
hadrianl Sep 15, 2023
3f0c0f5
perf: using cython
hadrianl Sep 18, 2023
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
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,7 @@ setup.py
docs
*.swp
*~
.env
.env
taos/*.c
taos/*.cpp
poetry.lock
58 changes: 58 additions & 0 deletions build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project :taos-connector-python
@File :build.py
@Author :hadrianl
@Date :2023/8/10 14:05
"""

from Cython.Build import cythonize, build_ext
from setuptools import Extension
# from setuptools.command.build_ext import build_ext
import platform

compiler_directives = {"language_level": 3, "embedsignature": True}


def build(setup_kwargs):
if platform.system() == "Linux":
extensions = [
Extension("taos._cinterface", ["taos/_cinterface.pyx"],
libraries=["taos"],
),
Extension("taos._parser", ["taos/_parser.pyx"]),
Extension("taos._objects", ["taos/_objects.pyx"],
libraries=["taos"],
),
Extension("taos._constants", ["taos/_constants.pyx"],
libraries=["taos"],
),
]
elif platform.system() == "Windows":
extensions = [
Extension("taos._cinterface", ["taos/_cinterface.pyx"],
libraries=["taos"],
include_dirs=[r"C:\TDengine\include"],
library_dirs=[r"C:\TDengine\driver"],
),
Extension("taos._parser", ["taos/_parser.pyx"]),
Extension("taos._objects", ["taos/_objects.pyx"],
libraries=["taos"],
include_dirs=[r"C:\TDengine\include"],
library_dirs=[r"C:\TDengine\driver"],
),
Extension("taos._constants", ["taos/_constants.pyx"],
libraries=["taos"],
include_dirs=[r"C:\TDengine\include"],
library_dirs=[r"C:\TDengine\driver"],
),
]
else:
raise Exception("unsupported platform")

setup_kwargs.update({
"ext_modules": cythonize(extensions, compiler_directives=compiler_directives, force=True),
"cmdclass": {"build_ext": build_ext},
})

48 changes: 48 additions & 0 deletions examples/cython/bind-multi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from taos._objects import TaosConnection, TaosMultiBinds
import datetime as dt
import pytz

conn = TaosConnection(host="localhost", timezone="Asia/Shanghai")
dbname = "pytest_taos_stmt_multi"
conn.execute("drop database if exists %s" % dbname)
conn.execute("create database if not exists %s" % dbname)
conn.select_db(dbname)

conn.execute(
"create table if not exists log(ts timestamp, bo bool, nil tinyint, \
ti tinyint, si smallint, ii int, bi bigint, tu tinyint unsigned, \
su smallint unsigned, iu int unsigned, bu bigint unsigned, \
ff float, dd double, bb binary(100), nn nchar(100), tt timestamp)",
)

stmt = conn.statement("insert into log values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)")


params = TaosMultiBinds(16)
params[0].timestamp((1626861392589, 1626861392590, 1626861392591))
params[1].bool((True, None, False))
params[2].tinyint([-128, -128, None]) # -128 is tinyint null
params[3].tinyint([0, 127, None])
params[4].smallint([3, None, 2])
params[5].int([3, 4, None])
params[6].bigint([3, 4, None])
params[7].tinyint_unsigned([3, 4, None])
params[8].smallint_unsigned([3, 4, None])
params[9].int_unsigned([3, 4, None])
params[10].bigint_unsigned([3, 4, None])
params[11].float([3, None, 1])
params[12].double([3, None, 1.2])
params[13].binary(["abc", "dddafadfadfadfadfa", None])
params[14].nchar(["涛思数据", None, "a long string with 中文字符"])
params[15].timestamp([dt.datetime.now(tz=pytz.timezone("Asia/Shanghai")), dt.datetime.now(tz=pytz.timezone("UTC")), dt.datetime.now()])
stmt.bind_param_batch(params)
stmt.execute()

assert stmt.affected_rows == 3

result = conn.query("select * from log")
for row in result:
print(row)

conn.execute("drop database if exists %s" % dbname)
conn.close()
45 changes: 45 additions & 0 deletions examples/cython/connection_usage_native_reference.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from taos._objects import TaosConnection

# ANCHOR: insert
conn = TaosConnection(host="localhost")
# Execute a sql, ignore the result set, just get affected rows. It's useful for DDL and DML statement.
conn.execute("DROP DATABASE IF EXISTS test")
conn.execute("CREATE DATABASE test")
# change database. same as execute "USE db"
conn.select_db("test")
conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (location INT)")
affected_row = conn.execute("INSERT INTO t1 USING weather TAGS(1) VALUES (now, 23.5) (now+1m, 23.5) (now+2m, 24.4)")
print("affected_row", affected_row)
# output:
# affected_row 3
# ANCHOR_END: insert

# ANCHOR: query
# Execute a sql and get its result set. It's useful for SELECT statement
result = conn.query("SELECT * from weather")

# Get fields from result
fields = result.fields
for field in fields:
print(field) # {name: ts, type: 9, bytes: 8}

# output:
# {name: ts, type: 9, bytes: 8}
# {name: temperature, type: 6, bytes: 4}
# {name: location, type: 4, bytes: 4}

# Get data from result as list of tuple
data = result.fetch_all()
print(data)
# output:
# [(datetime.datetime(2022, 4, 27, 9, 4, 25, 367000), 23.5, 1), (datetime.datetime(2022, 4, 27, 9, 5, 25, 367000), 23.5, 1), (datetime.datetime(2022, 4, 27, 9, 6, 25, 367000), 24.399999618530273, 1)]

# Or get data from result as a list of dict
# map_data = result.fetch_all_into_dict()
# print(map_data)
# output:
# [{'ts': datetime.datetime(2022, 4, 27, 9, 1, 15, 343000), 'temperature': 23.5, 'location': 1}, {'ts': datetime.datetime(2022, 4, 27, 9, 2, 15, 343000), 'temperature': 23.5, 'location': 1}, {'ts': datetime.datetime(2022, 4, 27, 9, 3, 15, 343000), 'temperature': 24.399999618530273, 'location': 1}]
# ANCHOR_END: query

conn.execute("DROP DATABASE IF EXISTS test")
conn.close()
45 changes: 45 additions & 0 deletions examples/cython/connection_usage_native_reference_with_req_id.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from taos._objects import TaosConnection

# ANCHOR: insert
conn = TaosConnection(host="localhost")
# Execute a sql, ignore the result set, just get affected rows. It's useful for DDL and DML statement.
conn.execute("DROP DATABASE IF EXISTS test", req_id=1)
conn.execute("CREATE DATABASE test", req_id=2)
# change database. same as execute "USE db"
conn.select_db("test")
conn.execute("CREATE STABLE weather(ts TIMESTAMP, temperature FLOAT) TAGS (location INT)", req_id=3)
affected_row = conn.execute("INSERT INTO t1 USING weather TAGS(1) VALUES (now, 23.5) (now+1m, 23.5) (now+2m, 24.4)", req_id=4)
print("affected_row", affected_row)
# output:
# affected_row 3
# ANCHOR_END: insert

# ANCHOR: query
# Execute a sql and get its result set. It's useful for SELECT statement
result = conn.query("SELECT * from weather", req_id=5)

# Get fields from result
fields = result.fields
for field in fields:
print(field) # {name: ts, type: 9, bytes: 8}

# output:
# {name: ts, type: 9, bytes: 8}
# {name: temperature, type: 6, bytes: 4}
# {name: location, type: 4, bytes: 4}

# Get data from result as list of tuple
data = result.fetch_all()
print(data)
# output:
# [(datetime.datetime(2022, 4, 27, 9, 4, 25, 367000), 23.5, 1), (datetime.datetime(2022, 4, 27, 9, 5, 25, 367000), 23.5, 1), (datetime.datetime(2022, 4, 27, 9, 6, 25, 367000), 24.399999618530273, 1)]

# Or get data from result as a list of dict
# map_data = result.fetch_all_into_dict()
# print(map_data)
# output:
# [{'ts': datetime.datetime(2022, 4, 27, 9, 1, 15, 343000), 'temperature': 23.5, 'location': 1}, {'ts': datetime.datetime(2022, 4, 27, 9, 2, 15, 343000), 'temperature': 23.5, 'location': 1}, {'ts': datetime.datetime(2022, 4, 27, 9, 3, 15, 343000), 'temperature': 24.399999618530273, 'location': 1}]
# ANCHOR_END: query

conn.execute("DROP DATABASE IF EXISTS test")
conn.close()
91 changes: 91 additions & 0 deletions examples/cython/cursor_execute_many.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
from taos._objects import TaosConnection

env = {
'user': "root",
'password': "taosdata",
'host': "localhost",
'port': 6030,
}


def make_context(config):
db_protocol = config.get('db_protocol', 'taos')
db_user = config['user']
db_pass = config['password']
db_host = config['host']
db_port = config['port']

db_url = f"{db_protocol}://{db_user}:{db_pass}@{db_host}:{db_port}"
print('dsn: ', db_url)

conn = TaosConnection(**config)

db_name = config.get('database', 'c_cursor')

return conn, db_name


def test_cursor():
conn, db_name = make_context(env)

cur = conn.cursor()

cur.execute(f"DROP DATABASE IF EXISTS {db_name}")
cur.execute(f"CREATE DATABASE {db_name}")
cur.execute(f"USE {db_name}")

cur.execute("create stable stb (ts timestamp, v1 int) tags(t1 int)")

create_table_data = [
{
"name": "tb1",
"t1": 1,
},
{
"name": "tb2",
"t1": 2,
},
{
"name": "tb3",
"t1": 3,
}
]

res = cur.executemany(
"create table {name} using stb tags({t1})",
create_table_data,
)
print(f"affected_rows: {res}")
assert res == 0

data = [
('2018-10-03 14:38:05.100', 219),
('2018-10-03 14:38:15.300', 218),
('2018-10-03 14:38:16.800', 221),
]

for table in create_table_data:
table_name = table['name']

res = cur.executemany(
f"insert into {table_name} values",
data,
)
print(f"affected_rows: {res}")
assert res == 3

cur.execute('select * from stb')

data = cur.fetchall()
column_names = [meta[0] for meta in cur.description]
print(column_names)
for r in data:
print(r)

cur.execute(f"DROP DATABASE IF EXISTS {db_name}")
cur.close()
conn.close()


if __name__ == "__main__":
test_cursor()
24 changes: 24 additions & 0 deletions examples/cython/demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from taos._objects import TaosConnection

conn = TaosConnection(host="localhost")
cursor = conn.cursor()

sql = "drop database if exists db"
cursor.execute(sql)
sql = "create database if not exists db"
cursor.execute(sql)
sql = "create table db.tb(ts timestamp, n int, bin binary(10), nc nchar(10))"
cursor.execute(sql)
sql = "insert into db.tb values (1650000000000, 1, 'abc', '北京')"
cursor.execute(sql)
sql = "insert into db.tb values (1650000000001, null, null, null)"
cursor.execute(sql)
sql = "select * from db.tb"
cursor.execute(sql)

for row in cursor:
print(row)

sql = "drop database if exists db"
cursor.execute(sql)
conn.close()
34 changes: 34 additions & 0 deletions examples/cython/import-json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import json
from taos._objects import TaosConnection
import requests

j = requests.get("http://api.coindesk.com/v1/bpi/currentprice.json").json()

# json to sql
ts = j["time"]["updatedISO"]
sql = "insert into"
for id in j["bpi"]:
bpi = j["bpi"][id]
sql += ' %s using price tags("%s","%s","%s") values("%s", %lf) ' % (
id,
bpi["code"],
bpi["symbol"],
bpi["description"],
ts,
bpi["rate_float"],
)

# sql to TDengine
conn = TaosConnection(host="localhost")
conn.execute("drop database if exists bpi")
conn.execute("create database if not exists bpi")
conn.execute("use bpi")
conn.execute(
"create stable if not exists price (ts timestamp, rate double)"
+ " tags (code binary(10), symbol binary(10), description binary(100))"
)
conn.execute(sql)
result = conn.query("select * from bpi.price")
print(result.fetch_all())
conn.execute("drop database if exists bpi")
conn.close()
25 changes: 25 additions & 0 deletions examples/cython/insert-lines.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from taos._objects import TaosConnection
from taos._constants import SmlProtocol, SmlPrecision

conn = TaosConnection(host="localhost")
dbname = "pytest_line"
conn.execute("drop database if exists %s" % dbname)
conn.execute("create database if not exists %s precision 'us'" % dbname)
conn.select_db(dbname)

lines = [
'st,t1=3i64,t2=4f64,t3="t3" c1=3i64,c3=L"pass",c2=false,c4=4f64 1626006833639000000',
]
conn.schemaless_insert(lines, SmlProtocol.LINE_PROTOCOL, SmlPrecision.NOT_CONFIGURED)
print("inserted")

conn.schemaless_insert(lines, SmlProtocol.LINE_PROTOCOL, SmlPrecision.NOT_CONFIGURED)

tb = conn.query("show tables").fetch_all()[0][0]
print(tb)
result = conn.query("select * from %s" % tb)
for row in result:
print(row)

conn.execute("drop database if exists %s" % dbname)
conn.close()
Loading