sqlobjects 1.2.4__py3-none-any.whl → 1.2.5__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.
Files changed (18) hide show
  1. sqlobjects/expressions/function.py +2 -0
  2. sqlobjects/expressions/mixins.py +19 -3
  3. sqlobjects/fields/types/comparators.py +54 -5
  4. sqlobjects/fields/types/registry.py +6 -4
  5. {sqlobjects-1.2.4.dist-info → sqlobjects-1.2.5.dist-info}/METADATA +1 -1
  6. {sqlobjects-1.2.4.dist-info → sqlobjects-1.2.5.dist-info}/RECORD +18 -18
  7. {sqlobjects-1.2.4.data → sqlobjects-1.2.5.data}/data/share/sqlobjects/rules/01-database-session-guide.md +0 -0
  8. {sqlobjects-1.2.4.data → sqlobjects-1.2.5.data}/data/share/sqlobjects/rules/02-model-definition-guide.md +0 -0
  9. {sqlobjects-1.2.4.data → sqlobjects-1.2.5.data}/data/share/sqlobjects/rules/03-query-operations-guide.md +0 -0
  10. {sqlobjects-1.2.4.data → sqlobjects-1.2.5.data}/data/share/sqlobjects/rules/04-crud-operations-guide.md +0 -0
  11. {sqlobjects-1.2.4.data → sqlobjects-1.2.5.data}/data/share/sqlobjects/rules/05-relationships-guide.md +0 -0
  12. {sqlobjects-1.2.4.data → sqlobjects-1.2.5.data}/data/share/sqlobjects/rules/06-validation-signals-guide.md +0 -0
  13. {sqlobjects-1.2.4.data → sqlobjects-1.2.5.data}/data/share/sqlobjects/rules/07-performance-guide.md +0 -0
  14. {sqlobjects-1.2.4.data → sqlobjects-1.2.5.data}/data/share/sqlobjects/rules/README.md +0 -0
  15. {sqlobjects-1.2.4.dist-info → sqlobjects-1.2.5.dist-info}/WHEEL +0 -0
  16. {sqlobjects-1.2.4.dist-info → sqlobjects-1.2.5.dist-info}/entry_points.txt +0 -0
  17. {sqlobjects-1.2.4.dist-info → sqlobjects-1.2.5.dist-info}/licenses/LICENSE +0 -0
  18. {sqlobjects-1.2.4.dist-info → sqlobjects-1.2.5.dist-info}/top_level.txt +0 -0
@@ -147,6 +147,8 @@ class FunctionExpression:
147
147
  for building complex database expressions.
148
148
  """
149
149
 
150
+ is_clause_element = False # prevent __getattr__ from proxying this to expression.is_clause_element
151
+
150
152
  if TYPE_CHECKING:
151
153
  # Inherit all method hints for IDE support
152
154
  def __new__(cls, *args, **kwargs) -> "FunctionExpression & _FunctionMethods": ... # type: ignore
@@ -247,9 +247,25 @@ class ColumnAttributeFunctionMixin(FunctionMixin):
247
247
  def extract(self, field: str) -> "FunctionExpression": ...
248
248
  def date_trunc(self, precision: str) -> "FunctionExpression": ...
249
249
 
250
- # JSON methods
251
- def extract_path(self, path) -> "FunctionExpression": ...
252
- def extract_text(self, path) -> "FunctionExpression": ...
250
+ # JSON methods (MySQL json type)
251
+ def json_extract(self, path: str) -> "FunctionExpression": ...
252
+ def json_unquote(self, path: str) -> "FunctionExpression": ...
253
+ def json_contains(self, other, path: str | None = None) -> "FunctionExpression": ...
254
+ def json_contains_path(self, *paths: str, match: str = "one") -> "FunctionExpression": ...
255
+ def json_length(self, path: str | None = None) -> "FunctionExpression": ...
256
+ def json_keys(self, path: str | None = None) -> "FunctionExpression": ...
257
+ def json_overlaps(self, other) -> "FunctionExpression": ...
258
+ def json_search(self, value: str, match: str = "one", path: str | None = None) -> "FunctionExpression": ...
259
+ def json_type(self) -> "FunctionExpression": ...
260
+
261
+ # JSONB methods (PostgreSQL jsonb type)
262
+ def contained_by(self, other) -> "FunctionExpression": ...
263
+ def has_key(self, other) -> "FunctionExpression": ...
264
+ def has_all(self, other) -> "FunctionExpression": ...
265
+ def has_any(self, other) -> "FunctionExpression": ...
266
+ def path_exists(self, other) -> "FunctionExpression": ...
267
+ def path_match(self, other) -> "FunctionExpression": ...
268
+ def delete_path(self, array) -> "FunctionExpression": ...
253
269
 
254
270
  # Common methods (all types)
255
271
  def sum(self) -> "FunctionExpression": ...
@@ -323,13 +323,62 @@ class DateTimeComparator(ComparatorMixin, DateTime.Comparator): # type: ignore[
323
323
 
324
324
 
325
325
  class JSONComparator(ComparatorMixin, JSON.Comparator): # type: ignore[reportIncompatibleMethodOverride]
326
- """JSON type comparator with JSON extraction and manipulation methods."""
326
+ """MySQL JSON type comparator. For PostgreSQL, use jsonb type instead."""
327
327
 
328
- def extract_path(self, path) -> FunctionExpression:
329
- return FunctionExpression(func.json_extract_path(self, path))
328
+ def json_extract(self, path: str) -> FunctionExpression:
329
+ """JSON_EXTRACT(col, path) - e.g. json_extract('$.name')"""
330
+ return FunctionExpression(func.json_extract(self, path))
330
331
 
331
- def extract_text(self, path) -> FunctionExpression:
332
- return FunctionExpression(func.json_extract_path_text(self, path))
332
+ def json_unquote(self, path: str) -> FunctionExpression:
333
+ """JSON_UNQUOTE(JSON_EXTRACT(col, path)) - returns unquoted string value"""
334
+ return FunctionExpression(func.json_unquote(func.json_extract(self, path)))
335
+
336
+ def json_contains(self, other, path: str | None = None) -> FunctionExpression:
337
+ """JSON_CONTAINS(col, val[, path]) - check if JSON contains value"""
338
+ import json
339
+
340
+ from sqlalchemy import literal
341
+
342
+ value = [other] if not isinstance(other, (list, dict)) else other
343
+ json_val = literal(json.dumps(value))
344
+ if path is not None:
345
+ return FunctionExpression(func.json_contains(self, json_val, path))
346
+ return FunctionExpression(func.json_contains(self, json_val))
347
+
348
+ def json_contains_path(self, *paths: str, match: str = "one") -> FunctionExpression:
349
+ """JSON_CONTAINS_PATH(col, 'one'|'all', path, ...) - check if path(s) exist"""
350
+ return FunctionExpression(func.json_contains_path(self, match, *paths))
351
+
352
+ def json_length(self, path: str | None = None) -> FunctionExpression:
353
+ """JSON_LENGTH(col[, path]) - array/object length"""
354
+ if path is not None:
355
+ return FunctionExpression(func.json_length(self, path))
356
+ return FunctionExpression(func.json_length(self))
357
+
358
+ def json_keys(self, path: str | None = None) -> FunctionExpression:
359
+ """JSON_KEYS(col[, path]) - return all keys as JSON array"""
360
+ if path is not None:
361
+ return FunctionExpression(func.json_keys(self, path))
362
+ return FunctionExpression(func.json_keys(self))
363
+
364
+ def json_overlaps(self, other) -> FunctionExpression:
365
+ """JSON_OVERLAPS(col, val) - check if two JSON documents share any key-value pairs (MySQL 8.0+)"""
366
+ import json
367
+
368
+ from sqlalchemy import literal
369
+
370
+ value = other if isinstance(other, str) else json.dumps(other)
371
+ return FunctionExpression(func.json_overlaps(self, literal(value)))
372
+
373
+ def json_search(self, value: str, match: str = "one", path: str | None = None) -> FunctionExpression:
374
+ """JSON_SEARCH(col, 'one'|'all', val[, path]) - find path of value"""
375
+ if path is not None:
376
+ return FunctionExpression(func.json_search(self, match, value, None, path))
377
+ return FunctionExpression(func.json_search(self, match, value))
378
+
379
+ def json_type(self) -> FunctionExpression:
380
+ """JSON_TYPE(col) - return JSON value type as string"""
381
+ return FunctionExpression(func.json_type(self))
333
382
 
334
383
 
335
384
  class BooleanComparator(ComparatorMixin, Boolean.Comparator): # type: ignore[reportIncompatibleMethodOverride]
@@ -1,9 +1,10 @@
1
1
  import inspect
2
2
  from typing import Any, Callable, NotRequired, TypedDict
3
3
 
4
+ from sqlalchemy.dialects.mysql import JSON
5
+ from sqlalchemy.dialects.postgresql import JSONB
4
6
  from sqlalchemy.sql.sqltypes import (
5
7
  ARRAY,
6
- JSON,
7
8
  BigInteger,
8
9
  Boolean,
9
10
  Date,
@@ -344,14 +345,15 @@ class TypeRegistry:
344
345
  (Interval, "interval", DateTimeComparator, [], {}),
345
346
  (LargeBinary, "binary", DefaultComparator, ["bytes"], {}),
346
347
  (Uuid, "uuid", StringComparator, [], {}),
347
- (JSON, "json", JSONComparator, ["dict"], {}),
348
348
  ]
349
349
 
350
- # Special types
350
+ # Special types: dialect-specific or non-standard types
351
351
  special_types = [
352
- (ARRAY, "array", DefaultComparator, [], {}),
352
+ (ARRAY, "array", DefaultComparator, [], {}), # PostgreSQL only
353
353
  (Enum, "enum", DefaultComparator, [], {}),
354
354
  (Auto, "auto", DefaultComparator, [], {}),
355
+ (JSON, "json", JSONComparator, ["dict"], {}), # MySQL: contains -> JSON_CONTAINS
356
+ (JSONB, "jsonb", JSONB.Comparator, [], {}), # PostgreSQL: contains -> @>
355
357
  ]
356
358
 
357
359
  for field_type, name, comparator, aliases, defaults in builtin_types + special_types:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlobjects
3
- Version: 1.2.4
3
+ Version: 1.2.5
4
4
  Summary: Django-style async ORM library based on SQLAlchemy with chainable queries, Q objects, and relationship loading
5
5
  Author-email: XtraVisions <gitadmin@xtravisions.com>, Chen Hao <chenhao@xtravisions.com>
6
6
  Maintainer-email: XtraVisions <gitadmin@xtravisions.com>, Chen Hao <chenhao@xtravisions.com>
@@ -17,8 +17,8 @@ sqlobjects/expressions/aggregate.py,sha256=Gh4HekOaUmYDkS8O4QnmEhuf73QD44dBuAgUL
17
17
  sqlobjects/expressions/base.py,sha256=L9zHa9gb9M88sA9JmUSpR9k5tr-9Pgknbajo1ZmhOpk,5177
18
18
  sqlobjects/expressions/cte.py,sha256=9NAPpvBpxIoWmhc7eL3MyI3pmw65b9Hz6WzdNr2iVzc,4440
19
19
  sqlobjects/expressions/explain.py,sha256=GpfJq_JPgBfkNa9xlPi1wvkqYR6hlgT4V6lq5y6ftCE,1210
20
- sqlobjects/expressions/function.py,sha256=Dk5e_26ZKVdOqWdpQkC_XZWndUmYoq_iAMRFiK1O448,15113
21
- sqlobjects/expressions/mixins.py,sha256=pwqFXl7csdcou-O3ztfZ760XLdREqr4br0S475v2BSc,10469
20
+ sqlobjects/expressions/function.py,sha256=vCDbZR2aSxwXPGn_S2d93pm4yc3Xd2N83Fgpu6HTyr4,15218
21
+ sqlobjects/expressions/mixins.py,sha256=y430mXrJoz9dn7BNO74ZCtFvP1P5IDJAC3c5t4-Ex3s,11595
22
22
  sqlobjects/expressions/scalar.py,sha256=TRg1cg70m5kLKK2d-IOCHk0hPD2WWtXYErlMYSz6zio,6034
23
23
  sqlobjects/expressions/subquery.py,sha256=Jhhcl-EJbCvZmC91f7mZI4yeJqYVEyWtODHgB0_tNjk,15065
24
24
  sqlobjects/expressions/terminal.py,sha256=3R3LsRMoUazpd3EVNYi_m1LXwx6l42kyv4zlosgsrN0,15024
@@ -37,8 +37,8 @@ sqlobjects/fields/relations/strategies.py,sha256=X4KkeBxwpCcBHWhcL9EGH2WTQ2NdZWB
37
37
  sqlobjects/fields/relations/utils.py,sha256=G1PbW1heCShUSfjaDIbqj4I0yODdy4j3udf0Ex70cOg,12487
38
38
  sqlobjects/fields/types/__init__.py,sha256=PaEslOWuQVZVUoVnUFtqF-sNHOvF9AEVhuDseqRr-GA,651
39
39
  sqlobjects/fields/types/base.py,sha256=aK-8UDYtUcqJtwxw_emR-WefKDhrQyp0BK7s-UKx4yw,463
40
- sqlobjects/fields/types/comparators.py,sha256=d9azQGpUGg7eNF_aR0wWjZDzL3sFClHNh-fyObQudgY,15556
41
- sqlobjects/fields/types/registry.py,sha256=52niJnXdpqRewFKyOyiU-EhygR7SSZ1RQsflZ4u7evI,14529
40
+ sqlobjects/fields/types/comparators.py,sha256=Q0w1O_b1nh7_47s2xV9PLZtZdStNc3hVk87LCcKgHD8,18000
41
+ sqlobjects/fields/types/registry.py,sha256=6wNs-Fa18QA6o9u57eJ2yZyojOi4SdIu6Xd9ROsvM7I,14792
42
42
  sqlobjects/internal/__init__.py,sha256=Vam4blEYmPIgxMJY5YI32btY6Q2SD49OaGduwnaSDsM,447
43
43
  sqlobjects/internal/operations.py,sha256=IDB6XiIDZUFBfm_uub6Jr77hgOAEpCQbLNLBAcHeflA,3561
44
44
  sqlobjects/internal/results.py,sha256=rTX4sIG9Eo9Ik3eTWKV116MPtNzGjdLAJIy8FdVGWBA,2216
@@ -54,17 +54,17 @@ sqlobjects/utils/__init__.py,sha256=NsJ52Fl_PaB-2WlOIJVGNPmgOnqPmvYRmp7uaq5zfYs,
54
54
  sqlobjects/utils/inspect.py,sha256=u-Q9VBoSGYCE_3Soy8jMuCAdM-P7IkSzTxqrJop_Ilk,2612
55
55
  sqlobjects/utils/naming.py,sha256=PmfNuEz-Twly2qREjKfMNulJt8TmOUJaxzFTuts3COg,1411
56
56
  sqlobjects/utils/pattern.py,sha256=FGCgobTpnmKjdAtQidHIg4Xa2CQLeP35F0VuX_1T1dk,14740
57
- sqlobjects-1.2.4.data/data/share/sqlobjects/rules/01-database-session-guide.md,sha256=lnqRpcDhYKdH-f0avW1jXcWt3qi7XBwkMt7clTs9Zvg,7601
58
- sqlobjects-1.2.4.data/data/share/sqlobjects/rules/02-model-definition-guide.md,sha256=i5gNJM-0bIJ2xSUu3mij8uB9kJC9EAc_439sCBqRph8,10977
59
- sqlobjects-1.2.4.data/data/share/sqlobjects/rules/03-query-operations-guide.md,sha256=BEZE_WUUhY6sEZDiDtrbInlV_UVIhbYETABJTNhu2JQ,10550
60
- sqlobjects-1.2.4.data/data/share/sqlobjects/rules/04-crud-operations-guide.md,sha256=abUEvRPSiSjX8enclXO5Uryox9Rt0WFeRcFkvHXfPf8,10085
61
- sqlobjects-1.2.4.data/data/share/sqlobjects/rules/05-relationships-guide.md,sha256=MJ23fYOTWqrLd54ENZLu3S3QRqbLf7joq-YhF6-V8OQ,12204
62
- sqlobjects-1.2.4.data/data/share/sqlobjects/rules/06-validation-signals-guide.md,sha256=i9WLLhyCDoWGkIYqH2D_XLn98oMbF1pB3-L-b5gRbT4,14294
63
- sqlobjects-1.2.4.data/data/share/sqlobjects/rules/07-performance-guide.md,sha256=rjR0DjT39poEBVaUxAzJBEaMaBrZKLVer1zXaNNYfxg,12851
64
- sqlobjects-1.2.4.data/data/share/sqlobjects/rules/README.md,sha256=d2n5ZZT8LGvjL60u_HlzXn2uA8FwoCgqG3fuAhvMFvM,2280
65
- sqlobjects-1.2.4.dist-info/licenses/LICENSE,sha256=ScFR7nvWIhar0d32Y-LA4vqp9zNmy1HSJia7UX7jU6c,1068
66
- sqlobjects-1.2.4.dist-info/METADATA,sha256=Wql2U7dUxjC3mK9nGp7iF7YoVpHJBbynF798QO4Kc0c,13740
67
- sqlobjects-1.2.4.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
68
- sqlobjects-1.2.4.dist-info/entry_points.txt,sha256=9Q3Ci55MawxkQhMlR_eLJui00_rYYIVO_Aq_Dm0u5MQ,76
69
- sqlobjects-1.2.4.dist-info/top_level.txt,sha256=brO5vDtCpn4L9dpX0EHpehbu4kcHaK_2Bbnwze35YKc,11
70
- sqlobjects-1.2.4.dist-info/RECORD,,
57
+ sqlobjects-1.2.5.data/data/share/sqlobjects/rules/01-database-session-guide.md,sha256=lnqRpcDhYKdH-f0avW1jXcWt3qi7XBwkMt7clTs9Zvg,7601
58
+ sqlobjects-1.2.5.data/data/share/sqlobjects/rules/02-model-definition-guide.md,sha256=i5gNJM-0bIJ2xSUu3mij8uB9kJC9EAc_439sCBqRph8,10977
59
+ sqlobjects-1.2.5.data/data/share/sqlobjects/rules/03-query-operations-guide.md,sha256=BEZE_WUUhY6sEZDiDtrbInlV_UVIhbYETABJTNhu2JQ,10550
60
+ sqlobjects-1.2.5.data/data/share/sqlobjects/rules/04-crud-operations-guide.md,sha256=abUEvRPSiSjX8enclXO5Uryox9Rt0WFeRcFkvHXfPf8,10085
61
+ sqlobjects-1.2.5.data/data/share/sqlobjects/rules/05-relationships-guide.md,sha256=MJ23fYOTWqrLd54ENZLu3S3QRqbLf7joq-YhF6-V8OQ,12204
62
+ sqlobjects-1.2.5.data/data/share/sqlobjects/rules/06-validation-signals-guide.md,sha256=i9WLLhyCDoWGkIYqH2D_XLn98oMbF1pB3-L-b5gRbT4,14294
63
+ sqlobjects-1.2.5.data/data/share/sqlobjects/rules/07-performance-guide.md,sha256=rjR0DjT39poEBVaUxAzJBEaMaBrZKLVer1zXaNNYfxg,12851
64
+ sqlobjects-1.2.5.data/data/share/sqlobjects/rules/README.md,sha256=d2n5ZZT8LGvjL60u_HlzXn2uA8FwoCgqG3fuAhvMFvM,2280
65
+ sqlobjects-1.2.5.dist-info/licenses/LICENSE,sha256=ScFR7nvWIhar0d32Y-LA4vqp9zNmy1HSJia7UX7jU6c,1068
66
+ sqlobjects-1.2.5.dist-info/METADATA,sha256=ex1EZKe_eq2x1rsSjnZZpgf5oIbTmQutoU6JTyTKx74,13740
67
+ sqlobjects-1.2.5.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
68
+ sqlobjects-1.2.5.dist-info/entry_points.txt,sha256=9Q3Ci55MawxkQhMlR_eLJui00_rYYIVO_Aq_Dm0u5MQ,76
69
+ sqlobjects-1.2.5.dist-info/top_level.txt,sha256=brO5vDtCpn4L9dpX0EHpehbu4kcHaK_2Bbnwze35YKc,11
70
+ sqlobjects-1.2.5.dist-info/RECORD,,