zodbc 0.9.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,10 @@
1
+ include _zodbc.zig
2
+ include PyFuncs.zig
3
+ include arrow.zig
4
+ include fetch_arrow.zig
5
+ include fetch_py.zig
6
+ include put_arrow.zig
7
+ include put_common.zig
8
+ include put_py.zig
9
+ include utils.zig
10
+ include fmt.zig
zodbc-0.9.1/PKG-INFO ADDED
@@ -0,0 +1,106 @@
1
+ Metadata-Version: 2.4
2
+ Name: zodbc
3
+ Version: 0.9.1
4
+ Summary: DBAPI2-like ODBC client with Apache Arrow support
5
+ Author: Felix Graßl
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/ffelixg/zodbc_py
8
+ Keywords: odbc,arrow,mssql,sql server
9
+ Classifier: Programming Language :: Python
10
+ Classifier: Topic :: Database
11
+ Classifier: Intended Audience :: Developers
12
+ Requires-Python: >=3.10
13
+ Description-Content-Type: text/markdown
14
+ Provides-Extra: pyarrow
15
+ Requires-Dist: pyarrow; extra == "pyarrow"
16
+
17
+ # zodbc
18
+
19
+ This odbc client tries to be compatible with the DB API 2 Specification, while also treating pyarrow compatibility as a first class citizen. At the moment it is tested with the msodbc driver. Compilation and installation is made easy by ziglang being a simple build dependency. The only system dependencies for compilation should be development headers for unixodbc (if on linux) and python.
20
+
21
+
22
+ # Installation
23
+
24
+ ```bash
25
+ pip install zodbc
26
+ ```
27
+
28
+
29
+ # Features
30
+
31
+
32
+ ## DB API 2
33
+
34
+ ```py
35
+ import zodbc
36
+ import os
37
+
38
+ con = zodbc.connect(os.environ["ODBC_CONSTR"]) # Connect with odbc connection string or DSN
39
+ cur = con.cursor() # Cursor, which translates to an odbc statement handle
40
+
41
+ # python parameters & return values, data types like str, int, bool, UUID, decimal, date, time, datetime
42
+ cur.execute("select ? a", [42])
43
+ assert cur.fetchone()[0] == 42
44
+
45
+ # Short hand alternative for getting column names from cur.description
46
+ assert [c[0] for c in cur.description] == cur.column_names == ["a"]
47
+
48
+ con.commit() # Transactions, autocommit is disabled by default
49
+ ```
50
+
51
+
52
+ ## Additional fetch methods
53
+
54
+ The DB API 2 fetch methods `fetchone`, `fetchmany` and `fetchall` return (lists of) tuples. Additionally, there is `fetch_named` which returns a list of named tuples, which allows accessing fields by attribute name like `row.a` as well as `fetch_dict` which returns a list of dicts. `fetch_dict` requires unique column names in the query. These methods are implemented directly in Zig and should therefore be more efficient than fetching tuples and converting them in python.
55
+
56
+
57
+ ## Apache Arrow
58
+
59
+ A query can be executed for every row in an Arrow RecordBatch.
60
+
61
+ ```py
62
+ import pyarrow as pa
63
+
64
+ cur.execute("drop table if exists t1")
65
+ cur.execute("create table t1(a int)")
66
+ cur.executemany_arrow(
67
+ "insert into t1(a) values(?)",
68
+ pa.RecordBatch.from_arrays([pa.array([1, 2, 3])], ["a"])
69
+ )
70
+ cur.execute("select * from t1").fetchall() # [(1,), (2,), (3,)]
71
+ ```
72
+
73
+ Arrow RecordBatches can be fetched from a query result.
74
+
75
+ ```py
76
+ cur.execute("select 1 a").fetch_arrow()
77
+ ```
78
+
79
+ Arrow RecordBatches can be used as a table valued parameter for MS SQL.
80
+
81
+ ```py
82
+ cur.execute("drop type if exists test_tabletype")
83
+ cur.execute("create type test_tabletype as table(a int)")
84
+ con.commit()
85
+
86
+ assert cur.execute(
87
+ "select sum(a) from ? where a <= ?",
88
+ [
89
+ zodbc.ArrowTVP(
90
+ zodbc.ArrowTVPType.from_name("test_tabletype"),
91
+ pa.RecordBatch.from_arrays([pa.array([1, 2, 3])], ["a"]),
92
+ ),
93
+ 2,
94
+ ]
95
+ ).fetchone()[0] == 3
96
+ ```
97
+
98
+
99
+ # Differences with pyodbc
100
+
101
+ - UUID is always returned as a python UUID object (no pyodbc.native_uuid global variable)
102
+ - No output conversion (add_output_converter connection method)
103
+ - More explicit:
104
+ - No `execute(query, param1, param2)` => params must be passed as sequence
105
+ - No Cursor.commit, instead use Cursor.connection.commit
106
+ - Connection.getinfo takes a string instead of the odbc enum value
@@ -0,0 +1,60 @@
1
+ const c = @import("c");
2
+ const Obj = *c.PyObject;
3
+
4
+ cls_datetime: Obj,
5
+ cls_date: Obj,
6
+ cls_time: Obj,
7
+ cls_timezone: Obj,
8
+ cls_timedelta: Obj,
9
+ cls_decimal: Obj,
10
+ func_decimal_intratio: Obj,
11
+ cls_uuid: Obj,
12
+
13
+ pub fn init() !@This() {
14
+ const mod_datetime = c.PyImport_ImportModule("datetime") orelse return error.PyErr;
15
+ defer c.Py_DECREF(mod_datetime);
16
+ const cls_datetime = c.PyObject_GetAttrString(mod_datetime, "datetime") orelse return error.PyErr;
17
+ errdefer c.Py_DECREF(cls_datetime);
18
+ const cls_date = c.PyObject_GetAttrString(mod_datetime, "date") orelse return error.PyErr;
19
+ errdefer c.Py_DECREF(cls_date);
20
+ const cls_time = c.PyObject_GetAttrString(mod_datetime, "time") orelse return error.PyErr;
21
+ errdefer c.Py_DECREF(cls_time);
22
+ const cls_timezone = c.PyObject_GetAttrString(mod_datetime, "timezone") orelse return error.PyErr;
23
+ errdefer c.Py_DECREF(cls_timezone);
24
+ const cls_timedelta = c.PyObject_GetAttrString(mod_datetime, "timedelta") orelse return error.PyErr;
25
+ errdefer c.Py_DECREF(cls_timedelta);
26
+
27
+ const mod_decimal = c.PyImport_ImportModule("decimal") orelse return error.PyErr;
28
+ defer c.Py_DECREF(mod_decimal);
29
+ const cls_decimal = c.PyObject_GetAttrString(mod_decimal, "Decimal") orelse return error.PyErr;
30
+ errdefer c.Py_DECREF(cls_decimal);
31
+ const func_decimal_intratio = c.PyObject_GetAttrString(cls_decimal, "as_integer_ratio") orelse return error.PyErr;
32
+ errdefer c.Py_DECREF(func_decimal_intratio);
33
+
34
+ const mod_uuid = c.PyImport_ImportModule("uuid") orelse return error.PyErr;
35
+ defer c.Py_DECREF(mod_uuid);
36
+ const cls_uuid = c.PyObject_GetAttrString(mod_uuid, "UUID") orelse return error.PyErr;
37
+ errdefer c.Py_DECREF(cls_uuid);
38
+
39
+ return .{
40
+ .cls_datetime = cls_datetime,
41
+ .cls_date = cls_date,
42
+ .cls_time = cls_time,
43
+ .cls_timezone = cls_timezone,
44
+ .cls_timedelta = cls_timedelta,
45
+ .cls_decimal = cls_decimal,
46
+ .func_decimal_intratio = func_decimal_intratio,
47
+ .cls_uuid = cls_uuid,
48
+ };
49
+ }
50
+
51
+ pub fn deinit(self: @This()) void {
52
+ c.Py_DECREF(self.cls_datetime);
53
+ c.Py_DECREF(self.cls_date);
54
+ c.Py_DECREF(self.cls_time);
55
+ c.Py_DECREF(self.cls_timezone);
56
+ c.Py_DECREF(self.cls_timedelta);
57
+ c.Py_DECREF(self.cls_decimal);
58
+ c.Py_DECREF(self.func_decimal_intratio);
59
+ c.Py_DECREF(self.cls_uuid);
60
+ }
zodbc-0.9.1/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # zodbc
2
+
3
+ This odbc client tries to be compatible with the DB API 2 Specification, while also treating pyarrow compatibility as a first class citizen. At the moment it is tested with the msodbc driver. Compilation and installation is made easy by ziglang being a simple build dependency. The only system dependencies for compilation should be development headers for unixodbc (if on linux) and python.
4
+
5
+
6
+ # Installation
7
+
8
+ ```bash
9
+ pip install zodbc
10
+ ```
11
+
12
+
13
+ # Features
14
+
15
+
16
+ ## DB API 2
17
+
18
+ ```py
19
+ import zodbc
20
+ import os
21
+
22
+ con = zodbc.connect(os.environ["ODBC_CONSTR"]) # Connect with odbc connection string or DSN
23
+ cur = con.cursor() # Cursor, which translates to an odbc statement handle
24
+
25
+ # python parameters & return values, data types like str, int, bool, UUID, decimal, date, time, datetime
26
+ cur.execute("select ? a", [42])
27
+ assert cur.fetchone()[0] == 42
28
+
29
+ # Short hand alternative for getting column names from cur.description
30
+ assert [c[0] for c in cur.description] == cur.column_names == ["a"]
31
+
32
+ con.commit() # Transactions, autocommit is disabled by default
33
+ ```
34
+
35
+
36
+ ## Additional fetch methods
37
+
38
+ The DB API 2 fetch methods `fetchone`, `fetchmany` and `fetchall` return (lists of) tuples. Additionally, there is `fetch_named` which returns a list of named tuples, which allows accessing fields by attribute name like `row.a` as well as `fetch_dict` which returns a list of dicts. `fetch_dict` requires unique column names in the query. These methods are implemented directly in Zig and should therefore be more efficient than fetching tuples and converting them in python.
39
+
40
+
41
+ ## Apache Arrow
42
+
43
+ A query can be executed for every row in an Arrow RecordBatch.
44
+
45
+ ```py
46
+ import pyarrow as pa
47
+
48
+ cur.execute("drop table if exists t1")
49
+ cur.execute("create table t1(a int)")
50
+ cur.executemany_arrow(
51
+ "insert into t1(a) values(?)",
52
+ pa.RecordBatch.from_arrays([pa.array([1, 2, 3])], ["a"])
53
+ )
54
+ cur.execute("select * from t1").fetchall() # [(1,), (2,), (3,)]
55
+ ```
56
+
57
+ Arrow RecordBatches can be fetched from a query result.
58
+
59
+ ```py
60
+ cur.execute("select 1 a").fetch_arrow()
61
+ ```
62
+
63
+ Arrow RecordBatches can be used as a table valued parameter for MS SQL.
64
+
65
+ ```py
66
+ cur.execute("drop type if exists test_tabletype")
67
+ cur.execute("create type test_tabletype as table(a int)")
68
+ con.commit()
69
+
70
+ assert cur.execute(
71
+ "select sum(a) from ? where a <= ?",
72
+ [
73
+ zodbc.ArrowTVP(
74
+ zodbc.ArrowTVPType.from_name("test_tabletype"),
75
+ pa.RecordBatch.from_arrays([pa.array([1, 2, 3])], ["a"]),
76
+ ),
77
+ 2,
78
+ ]
79
+ ).fetchone()[0] == 3
80
+ ```
81
+
82
+
83
+ # Differences with pyodbc
84
+
85
+ - UUID is always returned as a python UUID object (no pyodbc.native_uuid global variable)
86
+ - No output conversion (add_output_converter connection method)
87
+ - More explicit:
88
+ - No `execute(query, param1, param2)` => params must be passed as sequence
89
+ - No Cursor.commit, instead use Cursor.connection.commit
90
+ - Connection.getinfo takes a string instead of the odbc enum value