cygnet-orm 1.0.0__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.
- cygnet/__init__.py +521 -0
- cygnet/annotations.py +86 -0
- cygnet/arrays.py +111 -0
- cygnet/builders.py +1070 -0
- cygnet/cte.py +321 -0
- cygnet/executor.py +1442 -0
- cygnet/expression.py +611 -0
- cygnet/fts.py +125 -0
- cygnet/functions.py +101 -0
- cygnet/jsonb.py +112 -0
- cygnet/meta.py +264 -0
- cygnet/predicate.py +263 -0
- cygnet/proxy.py +168 -0
- cygnet/psycopg_db.py +185 -0
- cygnet/py.typed +0 -0
- cygnet/stubs.py +170 -0
- cygnet_orm-1.0.0.dist-info/METADATA +1090 -0
- cygnet_orm-1.0.0.dist-info/RECORD +20 -0
- cygnet_orm-1.0.0.dist-info/WHEEL +4 -0
- cygnet_orm-1.0.0.dist-info/licenses/LICENSE +21 -0
cygnet/arrays.py
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# arrays.py — Curated helpers for PostgreSQL array operators and functions.
|
|
2
|
+
#
|
|
3
|
+
# Mix of operator helpers (built on cygnet.op) and function helpers
|
|
4
|
+
# (built on cygnet.fn). ANY/ALL deserve special mention: they're not
|
|
5
|
+
# standalone predicates — they appear on the right side of a comparison,
|
|
6
|
+
# as in `value = ANY(arr_col)`. The any() / all() helpers below return
|
|
7
|
+
# FunctionCall expressions; pair them with `==` / `!=` / etc. or wrap
|
|
8
|
+
# with cygnet.op for non-standard comparisons.
|
|
9
|
+
#
|
|
10
|
+
# Index notes: @>, <@, and && are accelerated by GIN indexes on the
|
|
11
|
+
# array column. `=` and ordering operators use btree on the array as a
|
|
12
|
+
# whole (rarely useful). array_length / cardinality / unnest are not
|
|
13
|
+
# index-friendly — filter on a containment predicate first when possible.
|
|
14
|
+
#
|
|
15
|
+
# NULL handling: in arrays, NULL elements are not equal to anything, so
|
|
16
|
+
# `NULL = ANY(arr)` yields NULL (not true), even if arr contains NULL.
|
|
17
|
+
# Use `arr.contains(col, [None])` semantics with care — PG treats NULLs
|
|
18
|
+
# in arrays as distinct from absence.
|
|
19
|
+
#
|
|
20
|
+
# `ANY` also accepts a subquery (e.g. `= ANY(SELECT id FROM t)`); the
|
|
21
|
+
# any() helper here is array-flavoured but happens to render identically
|
|
22
|
+
# for either operand since both forms emit `ANY(<expr>)`.
|
|
23
|
+
#
|
|
24
|
+
# Usage:
|
|
25
|
+
# import cygnet.arrays as arr
|
|
26
|
+
# .WHERE(arr.contains(T.tags, ["python", "sql"]))
|
|
27
|
+
# .WHERE(T.id == arr.any(other_table.allowed_ids))
|
|
28
|
+
# .WHERE(arr.length(T.items) > 0)
|
|
29
|
+
|
|
30
|
+
from __future__ import annotations
|
|
31
|
+
|
|
32
|
+
from typing import Any
|
|
33
|
+
|
|
34
|
+
from .expression import FunctionCall, fn, op
|
|
35
|
+
from .predicate import Predicate
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def contains(a: Any, b: Any) -> Predicate:
|
|
39
|
+
"""`a @> b` — does array `a` contain every element of array `b`?"""
|
|
40
|
+
return op(a, "@>", b)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def contained_by(a: Any, b: Any) -> Predicate:
|
|
44
|
+
"""`a <@ b` — is array `a` contained by array `b`?"""
|
|
45
|
+
return op(a, "<@", b)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def overlaps(a: Any, b: Any) -> Predicate:
|
|
49
|
+
"""`a && b` — do the arrays share any element?"""
|
|
50
|
+
return op(a, "&&", b)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def concat(a: Any, b: Any) -> Predicate:
|
|
54
|
+
"""`a || b` — array concatenation."""
|
|
55
|
+
return op(a, "||", b)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def any(col: Any) -> FunctionCall: # noqa: A001 — shadows builtin intentionally
|
|
59
|
+
"""`ANY(col)` — for use on the right side of a comparison.
|
|
60
|
+
|
|
61
|
+
Example: `WHERE T.id = arr.any(other_col)` renders as
|
|
62
|
+
`T.id = ANY(other_col)`. Returns a FunctionCall, not a Predicate;
|
|
63
|
+
pair with `==`, `!=`, or another comparison to produce a WHERE-able
|
|
64
|
+
expression.
|
|
65
|
+
"""
|
|
66
|
+
return fn("ANY")(col)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def all(col: Any) -> FunctionCall: # noqa: A001 — shadows builtin intentionally
|
|
70
|
+
"""`ALL(col)` — like any(), but every element must satisfy the comparison.
|
|
71
|
+
|
|
72
|
+
Example: `WHERE T.score > arr.all(thresholds)` renders as
|
|
73
|
+
`T.score > ALL(thresholds)`.
|
|
74
|
+
"""
|
|
75
|
+
return fn("ALL")(col)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def length(col: Any, dim: int = 1) -> FunctionCall:
|
|
79
|
+
"""`array_length(col, dim)` — length along the given dimension (1-based).
|
|
80
|
+
|
|
81
|
+
Default dim=1 covers the common case of a 1-D array. Returns NULL
|
|
82
|
+
if the array is empty or the dimension doesn't exist — that's PG's
|
|
83
|
+
semantics, not Cygnet's.
|
|
84
|
+
"""
|
|
85
|
+
return fn("array_length")(col, dim)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def cardinality(col: Any) -> FunctionCall:
|
|
89
|
+
"""`cardinality(col)` — total element count regardless of dimensions.
|
|
90
|
+
|
|
91
|
+
Unlike length(), returns 0 (not NULL) for empty arrays.
|
|
92
|
+
"""
|
|
93
|
+
return fn("cardinality")(col)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def unnest(col: Any) -> FunctionCall:
|
|
97
|
+
"""`unnest(col)` — expand an array into rows.
|
|
98
|
+
|
|
99
|
+
Mostly useful in FROM (lateral) or SELECT contexts; less common in
|
|
100
|
+
WHERE. Returns a FunctionCall that renders as `unnest(col)`.
|
|
101
|
+
"""
|
|
102
|
+
return fn("unnest")(col)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def array_agg(col: Any) -> FunctionCall:
|
|
106
|
+
"""`array_agg(col)` — collect into an array (aggregate).
|
|
107
|
+
|
|
108
|
+
Re-exported here from cygnet.functions for discoverability alongside
|
|
109
|
+
the other array helpers.
|
|
110
|
+
"""
|
|
111
|
+
return fn("array_agg")(col)
|