sql-blocks 1.20250711__py3-none-any.whl → 1.20250713__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.
- sql_blocks/sql_blocks.py +48 -14
- {sql_blocks-1.20250711.dist-info → sql_blocks-1.20250713.dist-info}/METADATA +32 -2
- sql_blocks-1.20250713.dist-info/RECORD +7 -0
- sql_blocks-1.20250711.dist-info/RECORD +0 -7
- {sql_blocks-1.20250711.dist-info → sql_blocks-1.20250713.dist-info}/LICENSE +0 -0
- {sql_blocks-1.20250711.dist-info → sql_blocks-1.20250713.dist-info}/WHEEL +0 -0
- {sql_blocks-1.20250711.dist-info → sql_blocks-1.20250713.dist-info}/top_level.txt +0 -0
sql_blocks/sql_blocks.py
CHANGED
@@ -336,6 +336,10 @@ class Round(Function):
|
|
336
336
|
inputs = [FLOAT]
|
337
337
|
output = FLOAT
|
338
338
|
|
339
|
+
class Trunc(Function):
|
340
|
+
inputs = [FLOAT]
|
341
|
+
output = FLOAT
|
342
|
+
|
339
343
|
# --- Date Functions: ------------------------------------
|
340
344
|
class DateDiff(Function):
|
341
345
|
inputs = [DATE]
|
@@ -1681,8 +1685,11 @@ class CypherParser(Parser):
|
|
1681
1685
|
if token in self.TOKEN_METHODS:
|
1682
1686
|
return
|
1683
1687
|
if '*' in token:
|
1684
|
-
|
1685
|
-
|
1688
|
+
pk_field = token.replace('*', '')
|
1689
|
+
if not pk_field.isidentifier():
|
1690
|
+
pos = int(pk_field or '1')-1
|
1691
|
+
pk_field = self.queries[-1].values[SELECT][pos]
|
1692
|
+
self.queries[-1].key_field = pk_field.split('.')[-1]
|
1686
1693
|
return
|
1687
1694
|
# -------------------------------------------------------
|
1688
1695
|
def field_params() -> dict:
|
@@ -1706,6 +1713,8 @@ class CypherParser(Parser):
|
|
1706
1713
|
if group:
|
1707
1714
|
if not field:
|
1708
1715
|
field = group
|
1716
|
+
elif not alias:
|
1717
|
+
alias = group
|
1709
1718
|
extra_classes += [GroupBy]
|
1710
1719
|
if function:
|
1711
1720
|
if is_count and not field:
|
@@ -1713,7 +1722,9 @@ class CypherParser(Parser):
|
|
1713
1722
|
class_type = FUNCTION_CLASS.get(function)
|
1714
1723
|
if not class_type:
|
1715
1724
|
raise ValueError(f'Unknown function `{function}`.')
|
1716
|
-
class_list = [ class_type().As(alias
|
1725
|
+
class_list = [ class_type().As(alias, extra_classes) ]
|
1726
|
+
elif alias:
|
1727
|
+
class_list = [NamedField(alias)] + extra_classes
|
1717
1728
|
else:
|
1718
1729
|
class_list = [Field] + extra_classes
|
1719
1730
|
FieldList(field, class_list).add('', self.queries[-1])
|
@@ -2181,17 +2192,39 @@ MAIN_TAG = '__main__'
|
|
2181
2192
|
class CTEFactory:
|
2182
2193
|
def __init__(self, txt: str):
|
2183
2194
|
"""
|
2184
|
-
|
2195
|
+
SQL syntax:
|
2185
2196
|
---
|
2186
|
-
**SELECT
|
2197
|
+
**SELECT field, field
|
2187
2198
|
FROM** ( `sub_query1` ) **AS** `alias_1`
|
2188
2199
|
JOIN ( `sub_query2` ) **AS** `alias_2` **ON** `__join__`
|
2200
|
+
|
2201
|
+
Cypher syntax:
|
2202
|
+
---
|
2203
|
+
Table1(field, `function$`field`:alias`, `group@`) <- Table2(field)
|
2204
|
+
`...`MainTable(field)
|
2189
2205
|
"""
|
2190
2206
|
if parser_class(txt) == CypherParser:
|
2207
|
+
txt, main_script = txt.split('...')
|
2191
2208
|
query_list = Select.parse(txt, CypherParser)
|
2192
|
-
|
2193
|
-
|
2194
|
-
|
2209
|
+
if main_script:
|
2210
|
+
main_script = ''.join(main_script)
|
2211
|
+
if '(*)' in main_script:
|
2212
|
+
field_list = [
|
2213
|
+
re.split(
|
2214
|
+
r'\bas\b|\bAS\b', field
|
2215
|
+
)[-1].strip()
|
2216
|
+
for query in query_list
|
2217
|
+
for field in query.values.get(SELECT, [])
|
2218
|
+
]
|
2219
|
+
main_script = main_script.replace('(*)', '({}, *)'.format(
|
2220
|
+
','.join(field_list)
|
2221
|
+
))
|
2222
|
+
self.main = detect(main_script)
|
2223
|
+
alias = self.main.table_name
|
2224
|
+
else:
|
2225
|
+
alias = '_'.join(query.table_name for query in query_list)
|
2226
|
+
self.main = Select(alias)
|
2227
|
+
self.main.break_lines = False
|
2195
2228
|
query = join_queries(query_list)
|
2196
2229
|
self.cte_list = [CTE(alias, [query])]
|
2197
2230
|
return
|
@@ -2405,17 +2438,18 @@ def detect(text: str, join_method = join_queries, format: str='') -> Select | li
|
|
2405
2438
|
|
2406
2439
|
if __name__ == "__main__":
|
2407
2440
|
cte = CTEFactory(
|
2408
|
-
"Sales(year$ref_date:ref_year@, sum$quantity:qty_sold, vendor) <- Vendor(id, name@)"
|
2441
|
+
"Sales(year$ref_date:ref_year@, sum$quantity:qty_sold, vendor) <- Vendor(id, name:vendors_name@)"
|
2409
2442
|
# ^^^ ^^^ ^^^
|
2410
2443
|
# | | | ^^^ ^^^
|
2411
2444
|
# | | | | |
|
2412
|
-
# | | |
|
2445
|
+
# | | | Relate Sales to Vendor --------+ |
|
2413
2446
|
# | | | |
|
2414
|
-
# | | +----
|
2447
|
+
# | | +---- Call it `ref_year` and group it |
|
2415
2448
|
# | | |
|
2416
|
-
# | +--
|
2449
|
+
# | +-- Extracts the year from the `ref_date` field |
|
2417
2450
|
# | |
|
2418
|
-
# +---
|
2419
|
-
#
|
2451
|
+
# +--- The Sales table |
|
2452
|
+
# Also groups by vendor´s name ------------------+
|
2453
|
+
"...Annual_Sales_per_Vendor(*) -> Goal(year, target)"
|
2420
2454
|
)
|
2421
2455
|
print(cte)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sql_blocks
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.20250713
|
4
4
|
Summary: Allows you to create objects for parts of SQL query commands. Also to combine these objects by joining them, adding or removing parts...
|
5
5
|
Home-page: https://github.com/julio-cascalles/sql_blocks
|
6
6
|
Author: Júlio Cascalles
|
@@ -948,7 +948,7 @@ R2 = Recursive.create(
|
|
948
948
|
>> Note: Comments added later.
|
949
949
|
---
|
950
950
|
|
951
|
-
### CTEFactory class
|
951
|
+
### 17.3 - CTEFactory class
|
952
952
|
CTEFactory exchanges subqueries for CTEs, simply by passing the text of the "dirty" query:
|
953
953
|
|
954
954
|
*Example*:
|
@@ -992,4 +992,34 @@ results...
|
|
992
992
|
ORDER BY
|
993
993
|
u001.name
|
994
994
|
```
|
995
|
+
|
996
|
+
#### 17.3.1 - You can also pass a Cypher script like in the example below:
|
997
|
+
|
998
|
+
cte = CTEFactory(
|
999
|
+
"Sales(year$ref_date:ref_year@, sum$quantity:qty_sold, vendor)"
|
1000
|
+
" <- Vendor(id, name:vendors_name@)"
|
1001
|
+
"...Annual_Sales_per_Vendor(*) -> Goal(year, target)"
|
1002
|
+
)
|
1003
|
+
print(cte)
|
1004
|
+
|
1005
|
+

|
1006
|
+
|
1007
|
+
results...
|
1008
|
+
```
|
1009
|
+
WITH Annual_Sales_per_Vendor AS (
|
1010
|
+
SELECT ven.name as vendors_name, Year(sal.ref_date) as ref_year
|
1011
|
+
, Sum(sal.quantity) as qty_sold FROM Vendor ven LEFT JOIN Sales sal ON (ven.id = sal.vendor)
|
1012
|
+
GROUP BY ven.name, ref_year
|
1013
|
+
)
|
1014
|
+
SELECT
|
1015
|
+
aspv.ref_year,
|
1016
|
+
aspv.qty_sold,
|
1017
|
+
aspv.vendors_name,
|
1018
|
+
goa.target
|
1019
|
+
FROM
|
1020
|
+
Annual_Sales_per_Vendor aspv
|
1021
|
+
RIGHT JOIN Goal goa ON (aspv.ref_year = goa.year)
|
1022
|
+
```
|
1023
|
+
|
1024
|
+
|
995
1025
|
---
|
@@ -0,0 +1,7 @@
|
|
1
|
+
sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
|
2
|
+
sql_blocks/sql_blocks.py,sha256=h5toXPu_0Nw9VaifIXAVlLBOKAv1Oz2Iw2kQSVEbk4Y,84392
|
3
|
+
sql_blocks-1.20250713.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
4
|
+
sql_blocks-1.20250713.dist-info/METADATA,sha256=OnjjmdmJU39ADp7D1IS6FmC020iIqguDP1MbkKCdJtg,25388
|
5
|
+
sql_blocks-1.20250713.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
+
sql_blocks-1.20250713.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
|
7
|
+
sql_blocks-1.20250713.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
1
|
-
sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
|
2
|
-
sql_blocks/sql_blocks.py,sha256=JHQ0CzciUEodZoA0WjUYKDpC2VZWcFlDB9C2wrNc4rA,83004
|
3
|
-
sql_blocks-1.20250711.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
4
|
-
sql_blocks-1.20250711.dist-info/METADATA,sha256=fci6o5QrXStVrXylRQ7QaCpO9jid0P6eON6xMK4Rob0,24486
|
5
|
-
sql_blocks-1.20250711.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
-
sql_blocks-1.20250711.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
|
7
|
-
sql_blocks-1.20250711.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|