jupyter-duckdb 1.2.7__py3-none-any.whl → 1.2.101__py3-none-any.whl

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,173 @@
1
+ from duckdb_kernel.util.ResultSetComparator import ResultSetComparator
2
+
3
+
4
+ def test_equals():
5
+ rsc = ResultSetComparator([
6
+ (1, "Alice"),
7
+ (3, "Charlie")
8
+ ], [
9
+ (1, "Alice"),
10
+ (3, "Charlie")
11
+ ])
12
+
13
+ assert rsc.left_only == []
14
+ assert rsc.right_only == []
15
+ assert rsc.ordered_left_only == []
16
+ assert rsc.ordered_right_only == []
17
+
18
+
19
+ def test_equals_only_unordered():
20
+ rsc = ResultSetComparator([
21
+ (1, "Alice"),
22
+ (3, "Charlie")
23
+ ], [
24
+ (3, "Charlie"),
25
+ (1, "Alice")
26
+ ])
27
+
28
+ assert rsc.left_only == []
29
+ assert rsc.right_only == []
30
+ assert rsc.ordered_left_only == [(3, "Charlie")]
31
+ assert rsc.ordered_right_only == [(1, "Alice")]
32
+
33
+
34
+ def test_missing():
35
+ # first missing
36
+ rsc = ResultSetComparator([
37
+ (1, "Alice"),
38
+ (2, "Bob"),
39
+ (3, "Charlie")
40
+ ], [
41
+ (2, "Bob"),
42
+ (3, "Charlie")
43
+ ])
44
+
45
+ assert rsc.left_only == [(1, "Alice")]
46
+ assert rsc.right_only == []
47
+ assert rsc.ordered_left_only == [(1, "Alice")]
48
+ assert rsc.ordered_right_only == []
49
+
50
+ # middle missing
51
+ rsc = ResultSetComparator([
52
+ (1, "Alice"),
53
+ (2, "Bob"),
54
+ (3, "Charlie")
55
+ ], [
56
+ (1, "Alice"),
57
+ (3, "Charlie")
58
+ ])
59
+
60
+ assert rsc.left_only == [(2, "Bob")]
61
+ assert rsc.right_only == []
62
+ assert rsc.ordered_left_only == [(2, "Bob")]
63
+ assert rsc.ordered_right_only == []
64
+
65
+ # last missing
66
+ rsc = ResultSetComparator([
67
+ (1, "Alice"),
68
+ (2, "Bob"),
69
+ (3, "Charlie")
70
+ ], [
71
+ (1, "Alice"),
72
+ (2, "Bob")
73
+ ])
74
+
75
+ assert rsc.left_only == [(3, "Charlie")]
76
+ assert rsc.right_only == []
77
+ assert rsc.ordered_left_only == [(3, "Charlie")]
78
+ assert rsc.ordered_right_only == []
79
+
80
+
81
+ def test_unnecessary():
82
+ # first unnecessary
83
+ rsc = ResultSetComparator([
84
+ (2, "Bob"),
85
+ (3, "Charlie")
86
+ ], [
87
+ (1, "Alice"),
88
+ (2, "Bob"),
89
+ (3, "Charlie")
90
+ ])
91
+
92
+ assert rsc.left_only == []
93
+ assert rsc.right_only == [(1, "Alice")]
94
+ assert rsc.ordered_left_only == []
95
+ assert rsc.ordered_right_only == [(1, "Alice")]
96
+
97
+ # middle unnecessary
98
+ rsc = ResultSetComparator([
99
+ (1, "Alice"),
100
+ (3, "Charlie")
101
+ ], [
102
+ (1, "Alice"),
103
+ (2, "Bob"),
104
+ (3, "Charlie")
105
+ ])
106
+
107
+ assert rsc.left_only == []
108
+ assert rsc.right_only == [(2, "Bob")]
109
+ assert rsc.ordered_left_only == []
110
+ assert rsc.ordered_right_only == [(2, "Bob")]
111
+
112
+ # last unnecessary
113
+ rsc = ResultSetComparator([
114
+ (1, "Alice"),
115
+ (2, "Bob")
116
+ ], [
117
+ (1, "Alice"),
118
+ (2, "Bob"),
119
+ (3, "Charlie")
120
+ ])
121
+
122
+ assert rsc.left_only == []
123
+ assert rsc.right_only == [(3, "Charlie")]
124
+ assert rsc.ordered_left_only == []
125
+ assert rsc.ordered_right_only == [(3, "Charlie")]
126
+
127
+
128
+ def test_repeating():
129
+ # equal
130
+ rsc = ResultSetComparator([
131
+ (2, "Bob"),
132
+ (2, "Bob"),
133
+ (3, "Charlie")
134
+ ], [
135
+ (2, "Bob"),
136
+ (2, "Bob"),
137
+ (3, "Charlie")
138
+ ])
139
+
140
+ assert rsc.left_only == []
141
+ assert rsc.right_only == []
142
+ assert rsc.ordered_left_only == []
143
+ assert rsc.ordered_right_only == []
144
+
145
+ # missing
146
+ rsc = ResultSetComparator([
147
+ (2, "Bob"),
148
+ (2, "Bob"),
149
+ (3, "Charlie")
150
+ ], [
151
+ (2, "Bob"),
152
+ (3, "Charlie")
153
+ ])
154
+
155
+ assert rsc.left_only == [(2, "Bob")]
156
+ assert rsc.right_only == []
157
+ assert rsc.ordered_left_only == [(2, "Bob")]
158
+ assert rsc.ordered_right_only == []
159
+
160
+ # unnecessary
161
+ rsc = ResultSetComparator([
162
+ (2, "Bob"),
163
+ (3, "Charlie")
164
+ ], [
165
+ (2, "Bob"),
166
+ (2, "Bob"),
167
+ (3, "Charlie")
168
+ ])
169
+
170
+ assert rsc.left_only == []
171
+ assert rsc.right_only == [(2, "Bob")]
172
+ assert rsc.ordered_left_only == []
173
+ assert rsc.ordered_right_only == [(2, "Bob")]
@@ -0,0 +1,48 @@
1
+ import pytest
2
+
3
+ from duckdb_kernel.db.error import EmptyResultError
4
+ from . import Connection
5
+
6
+
7
+ def test_simple_queries():
8
+ query = 'SELECT Username FROM Users'
9
+
10
+ with Connection() as con:
11
+ assert con.execute_sql(query) == [
12
+ ('Alice',),
13
+ ('Bob',),
14
+ ('Charlie',)
15
+ ]
16
+
17
+
18
+ def test_empty_result():
19
+ with Connection() as con:
20
+ query = "SELECT Username FROM Users WHERE Username = 'abcdef'"
21
+ assert con.execute_sql(query) == []
22
+
23
+ with Connection() as con:
24
+ query = 'CREATE TABLE foo (bar INTEGER PRIMARY KEY)'
25
+ try:
26
+ assert con.execute_sql(query) == []
27
+ except EmptyResultError:
28
+ pass
29
+
30
+
31
+ def test_empty_queries():
32
+ for query in [
33
+ '',
34
+ ' ',
35
+ '\n',
36
+ '-- this is an empty query too'
37
+ ]:
38
+ with pytest.raises(EmptyResultError):
39
+ with Connection() as con:
40
+ con.execute_sql(query)
41
+
42
+ with pytest.raises(Exception):
43
+ with Connection() as con:
44
+ query = '-- this is a query with syntax errors\nFOR foo IN bar'
45
+ try:
46
+ con.execute_sql(query)
47
+ except EmptyResultError:
48
+ pass
@@ -0,0 +1,154 @@
1
+ from decimal import Decimal
2
+
3
+ PLOTLY_VERSION = '3.0.1'
4
+
5
+ import json
6
+ from uuid import uuid4
7
+ from typing import Dict, List, Optional
8
+
9
+ __PLOTLY_INITIALIZED = False
10
+
11
+
12
+ def __init() -> str:
13
+ global __PLOTLY_INITIALIZED
14
+
15
+ if not __PLOTLY_INITIALIZED:
16
+ __PLOTLY_INITIALIZED = True
17
+ return f'<script src="https://cdn.plot.ly/plotly-{PLOTLY_VERSION}.min.js"></script>'
18
+ else:
19
+ return ''
20
+
21
+
22
+ def __div_id() -> str:
23
+ return f'div-{str(uuid4())}'
24
+
25
+
26
+ def __layout(title: Optional[str]):
27
+ layout = {
28
+ 'dragmode': False,
29
+ 'xaxis': {
30
+ 'rangeselector': {
31
+ 'visible': False
32
+ }
33
+ }
34
+ }
35
+
36
+ if title is not None:
37
+ layout['title'] = {
38
+ 'text': title,
39
+ 'font': {
40
+ 'family': 'sans-serif',
41
+ 'size': 32,
42
+ 'color': 'rgb(0, 0, 0)'
43
+ },
44
+ 'xanchor': 'center'
45
+ }
46
+
47
+ return layout
48
+
49
+
50
+ def __config():
51
+ return {
52
+ 'displayModeBar': False,
53
+ 'scrollZoom': False
54
+ }
55
+
56
+
57
+ def __fix_decimal(x: List):
58
+ return [float(x) if isinstance(x, Decimal) else x
59
+ for x in x]
60
+
61
+
62
+ def draw_chart(title: Optional[str], traces: List[Dict] | Dict) -> str:
63
+ init = __init()
64
+ div_id = __div_id()
65
+ layout = __layout(title)
66
+ config = __config()
67
+
68
+ if not isinstance(traces, str):
69
+ traces = json.dumps(traces)
70
+
71
+ return f'''
72
+ {init}
73
+ <div id="{div_id}"></div>
74
+ <script type="text/javascript">
75
+ Plotly.newPlot('{div_id}', {traces}, {json.dumps(layout)}, {json.dumps(config)});
76
+ </script>
77
+ '''
78
+
79
+
80
+ def draw_scatter_chart(title: Optional[str], x, **ys) -> str:
81
+ return draw_chart(title, [
82
+ {
83
+ 'x': __fix_decimal(x),
84
+ 'y': __fix_decimal(y),
85
+ 'mode': 'markers',
86
+ 'type': 'scatter',
87
+ 'name': name
88
+ }
89
+ for name, y in ys.items()
90
+ ])
91
+
92
+
93
+ def draw_line_chart(title: Optional[str], x, **ys) -> str:
94
+ return draw_chart(title, [
95
+ {
96
+ 'x': __fix_decimal(x),
97
+ 'y': __fix_decimal(y),
98
+ 'mode': 'lines+markers',
99
+ 'name': name
100
+ }
101
+ for name, y in ys.items()
102
+ ])
103
+
104
+
105
+ def draw_bar_chart(title: Optional[str], x, **ys) -> str:
106
+ return draw_chart(title, [
107
+ {
108
+ 'x': __fix_decimal(x),
109
+ 'y': __fix_decimal(y),
110
+ 'type': 'bar',
111
+ 'name': name
112
+ }
113
+ for name, y in ys.items()
114
+ ])
115
+
116
+
117
+ def draw_pie_chart(title: Optional[str], x, y) -> str:
118
+ return draw_chart(title, [{
119
+ 'values': __fix_decimal(y),
120
+ 'labels': __fix_decimal(x),
121
+ 'type': 'pie'
122
+ }])
123
+
124
+
125
+ def draw_bubble_chart(title: Optional[str], x, y, s, c) -> str:
126
+ return draw_chart(title, [{
127
+ 'x': __fix_decimal(x),
128
+ 'y': __fix_decimal(y),
129
+ 'mode': 'markers',
130
+ 'marker': {
131
+ 'size': __fix_decimal(s),
132
+ 'color': __fix_decimal(c)
133
+ }
134
+ }])
135
+
136
+
137
+ def draw_heatmap_chart(title: Optional[str], x, y, z) -> str:
138
+ return draw_chart(title, [{
139
+ 'x': __fix_decimal(x[0]),
140
+ 'y': __fix_decimal(y[0]),
141
+ 'z': [__fix_decimal(v) for v in z[0]],
142
+ 'type': 'heatmap'
143
+ }])
144
+
145
+
146
+ __all__ = [
147
+ 'draw_chart',
148
+ 'draw_scatter_chart',
149
+ 'draw_line_chart',
150
+ 'draw_bar_chart',
151
+ 'draw_pie_chart',
152
+ 'draw_bubble_chart',
153
+ 'draw_heatmap_chart',
154
+ ]
@@ -1,2 +1,3 @@
1
+ from .Plotly import *
1
2
  from .RATreeDrawer import RATreeDrawer
2
3
  from .SchemaDrawer import SchemaDrawer
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: jupyter-duckdb
3
- Version: 1.2.7
3
+ Version: 1.2.101
4
4
  Summary: a basic wrapper kernel for DuckDB
5
5
  Home-page: https://github.com/erictroebs/jupyter-duckdb
6
6
  Author: Eric Tröbs
@@ -14,7 +14,7 @@ Description-Content-Type: text/markdown
14
14
  Requires-Dist: jupyter
15
15
  Requires-Dist: graphviz==0.20.3
16
16
  Requires-Dist: checkmarkandcross
17
- Requires-Dist: duckdb==1.2.0
17
+ Requires-Dist: duckdb==1.2.1
18
18
  Dynamic: author
19
19
  Dynamic: author-email
20
20
  Dynamic: classifier
@@ -1,7 +1,7 @@
1
1
  duckdb_kernel/__init__.py,sha256=6auU6zeJrsA4fxPSr2PYamS8fG-SMXTn5YQFXF2cseo,33
2
2
  duckdb_kernel/__main__.py,sha256=Z3GwHEBWoQjNm2Y84ijnbA0Lk66L7nsFREuqhZ_ptk0,165
3
3
  duckdb_kernel/kernel.json,sha256=_7E8Ci2FSdCvnzCjsOaue8QE8AvpS5JLQuxORO5IGtA,127
4
- duckdb_kernel/kernel.py,sha256=iiX9JzSgIvno1tWc2ZJGYHts8J3P7md4yanMrsbMJkY,22454
4
+ duckdb_kernel/kernel.py,sha256=qURs-uIdQgnqZKSP0Z2Q8Eo_rrdMMdTcHdpUsURxXN8,26470
5
5
  duckdb_kernel/db/Column.py,sha256=GM5P6sFdlYK92hiKln5-6038gIDOTxh1AYbR4kiga_w,559
6
6
  duckdb_kernel/db/Connection.py,sha256=5pH-CwGh-r9Q2QwJKGSxvoINBU-sqmvZyG4Q1digfeE,599
7
7
  duckdb_kernel/db/Constraint.py,sha256=1YgUHk7s8mHCVedbcuJKyXDykj7_ybbwT3Dk9p2VMis,287
@@ -21,7 +21,7 @@ duckdb_kernel/db/implementation/sqlite/__init__.py,sha256=HKogB1es4wOiQUoh7_eT32
21
21
  duckdb_kernel/magics/MagicCommand.py,sha256=l0EmnqgGZ0HyqQhdTljAaftflVo_RYp-U5UiDftYxAA,3180
22
22
  duckdb_kernel/magics/MagicCommandCallback.py,sha256=9XVidNtzs8Lwq_T59VrH89t5LUgJcc5C7grusElXVW4,1041
23
23
  duckdb_kernel/magics/MagicCommandException.py,sha256=MwuWkpA6NoCqz437urdI0RVXhbSbVdziuRoi7slYFPc,49
24
- duckdb_kernel/magics/MagicCommandHandler.py,sha256=TCCtAEaop5yTUn2af4wzcReEto3nql-40-DpIdIjKEw,4367
24
+ duckdb_kernel/magics/MagicCommandHandler.py,sha256=noRm22EsfTZI_FL_N15f6NYbZSPvejvS24rlA5hkDkQ,4730
25
25
  duckdb_kernel/magics/StringWrapper.py,sha256=W6qIfeHU51do1edd6yXgw6K7orzjwSHU4oWAI5DuKEE,96
26
26
  duckdb_kernel/magics/__init__.py,sha256=DA8gnQeRCUt1Scy3_NQ9w5CPmMEY9i8YwB-g392pN1U,204
27
27
  duckdb_kernel/parser/DCParser.py,sha256=16c1mxa494KP9OreUKQHsSQKoDGZ7NNp2u_gi_D-dkw,2293
@@ -44,11 +44,11 @@ duckdb_kernel/parser/elements/binary/And.py,sha256=0jgetTG8yo5TJSeK70Kj-PI9ERyek
44
44
  duckdb_kernel/parser/elements/binary/ArrowLeft.py,sha256=u4fZSoyT9lfvWXBwuhUl4DdjVZAOqyVIKmMVbpElLD4,203
45
45
  duckdb_kernel/parser/elements/binary/ConditionalSet.py,sha256=sZ3qrxPux7pb3fMrlyBg4Hw7n4-Ln-AeN70_Jp5dAPo,17652
46
46
  duckdb_kernel/parser/elements/binary/Cross.py,sha256=jVY3cvD6qDWZkJ7q74lFUPO2VdDt4aAjdk2YAfg-ZC4,687
47
- duckdb_kernel/parser/elements/binary/Difference.py,sha256=ZVRgJHYVMOFwnc97oPvGtKvLvHsjSCsn2Aao6ymxY8Y,742
48
- duckdb_kernel/parser/elements/binary/Divide.py,sha256=d7mzaOeRYSRO1F-2IHsv_C939TuYtLppbf4-5GSRJXs,265
49
- duckdb_kernel/parser/elements/binary/Division.py,sha256=Tq98RzGHN7QYF3R2ZVpwIiLhSIMQXzRgIuZ7l0D2fXg,1624
47
+ duckdb_kernel/parser/elements/binary/Difference.py,sha256=4nyHhjo09UmYjtGNC3xGQxV5ROzCGOpPkyerUN-AlF4,746
48
+ duckdb_kernel/parser/elements/binary/Divide.py,sha256=ubekU4C1wkCTidUSMLEj5neheRx0QjhWSrsPGuXTa1g,265
49
+ duckdb_kernel/parser/elements/binary/Division.py,sha256=FOYxmeNGljRETwygtVn102POCUmt71t9DXdAnLFCXZM,1535
50
50
  duckdb_kernel/parser/elements/binary/Equal.py,sha256=xd5eMwVwM7thXqmoBg-JSux4y6osxxznNzaChmgrnGI,192
51
- duckdb_kernel/parser/elements/binary/FullOuterJoin.py,sha256=WwV9jVFXr0FkfOOGKNZAiEjFKO_l0ND3RAvJYKEyVzY,1133
51
+ duckdb_kernel/parser/elements/binary/FullOuterJoin.py,sha256=W6S3rNSX0eWWtowRd6KbZ4RJqzhJUOvNt2IABmkLMJo,1383
52
52
  duckdb_kernel/parser/elements/binary/GreaterThan.py,sha256=lW7EPYjwwZ1VLZOE4ai6MBW7Zq5itsUTi_v6FxoAuU0,204
53
53
  duckdb_kernel/parser/elements/binary/GreaterThanEqual.py,sha256=gO1I3J5CZwrpqZb5Oc-WJ_fCnGylpj4YKl4s-ZAr_-4,286
54
54
  duckdb_kernel/parser/elements/binary/Intersection.py,sha256=K6NrwcLTJ1BUccifVQ2R2YHR5B71LhjuLhOalxZcM0g,757
@@ -74,16 +74,22 @@ duckdb_kernel/parser/tokenizer/__init__.py,sha256=EOSmfc2RJwtB5cE1Hhj1JAra97tckx
74
74
  duckdb_kernel/parser/util/RenamableColumn.py,sha256=LxJhFDMUv_OxYYDLwKn63QGpBRfs08jVvhuJTzRtc9c,704
75
75
  duckdb_kernel/parser/util/RenamableColumnList.py,sha256=5oEDbtvl4YfHbkxu_Ny2pc0EYnhCZsf7EeoNQvftbrU,3281
76
76
  duckdb_kernel/parser/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
+ duckdb_kernel/tests/__init__.py,sha256=MxC-m85ZyYQVn5_AJyEtXX1T5oQPngjW-Zxa_gpfXLE,2715
78
+ duckdb_kernel/tests/test_dc.py,sha256=HPJ6JGB7yXVKIOnDHB8KwX1A16ljU0I5Y8VFcJs-KVI,15192
79
+ duckdb_kernel/tests/test_ra.py,sha256=UENizwUqSnaObrvfliwkOakBQqNIh8tsQsgtYQ807MY,52371
80
+ duckdb_kernel/tests/test_result_comparison.py,sha256=TQVLPKKNyV2k3i4jCfasetPfVfCzgYZr92wxQmlzPnA,3859
81
+ duckdb_kernel/tests/test_sql.py,sha256=p7UEokoJs2xc-url7xQ4PmWKxtExrDDYnMeoyR1JD0A,1208
77
82
  duckdb_kernel/util/ResultSetComparator.py,sha256=RZDIfjJyx8-eR-HIqQlEYgZd_V1ympbszpVRF4TlA7o,2262
78
83
  duckdb_kernel/util/SQL.py,sha256=-uRfa0IwEQueZNZ7vkBPczLuvm_87y4_nnMBx3FgqNk,643
79
84
  duckdb_kernel/util/TestError.py,sha256=iwlGHr9j6pFDa2cGxqGyvJ-exrFUtPJjVm_OhHi4n3g,97
80
85
  duckdb_kernel/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
86
  duckdb_kernel/util/formatting.py,sha256=cbt0CtERnqtzd97mLrOjeJpqM2Lo6pW96BjAYqrOTD8,793
82
87
  duckdb_kernel/visualization/Drawer.py,sha256=D0LkiGMvuJ2v6cQSg_axLTGaM4VXAJEQJAynvedQ3So,296
88
+ duckdb_kernel/visualization/Plotly.py,sha256=5MDOHJsWiIYnQt4ZtKqQ69KcHetbO3N9PzJ8ZZW5CIo,3408
83
89
  duckdb_kernel/visualization/RATreeDrawer.py,sha256=j-Vy1zpYMzwZ3CsphyfPW-J7ou9a9tM6aXXgAlQTgDI,2128
84
90
  duckdb_kernel/visualization/SchemaDrawer.py,sha256=9K-TUUmyeGdMYMTFQJ7evIU3p8p2KyMKeizUc7-y8co,3015
85
- duckdb_kernel/visualization/__init__.py,sha256=5eMJmxJ01XAXcgWDn3t70eSZF2PGaXdNo6GK-x-0H3s,78
86
- jupyter_duckdb-1.2.7.dist-info/METADATA,sha256=g002q8FOyFbbZlRm-5qyDrf-yb_7n2bok9HqNXSvpbY,9113
87
- jupyter_duckdb-1.2.7.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
88
- jupyter_duckdb-1.2.7.dist-info/top_level.txt,sha256=KvRRPMnmkQNuhyBsXoPmwyt26LRDp0O-0HN6u0Dm5jA,14
89
- jupyter_duckdb-1.2.7.dist-info/RECORD,,
91
+ duckdb_kernel/visualization/__init__.py,sha256=37a-YUXb7Hr4NJCMatpjtmwP2FOPME-5wUWpszrYEMk,100
92
+ jupyter_duckdb-1.2.101.dist-info/METADATA,sha256=xNQwQu4VWyfFuHjDPDENmpxnHuO2eVzN0_c9ZklAe1Q,9115
93
+ jupyter_duckdb-1.2.101.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
94
+ jupyter_duckdb-1.2.101.dist-info/top_level.txt,sha256=KvRRPMnmkQNuhyBsXoPmwyt26LRDp0O-0HN6u0Dm5jA,14
95
+ jupyter_duckdb-1.2.101.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.2)
2
+ Generator: setuptools (76.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5