sql-blocks 1.25.26011923__py3-none-any.whl → 1.25.30011644__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 +53 -37
- {sql_blocks-1.25.26011923.dist-info → sql_blocks-1.25.30011644.dist-info}/METADATA +30 -1
- sql_blocks-1.25.30011644.dist-info/RECORD +7 -0
- sql_blocks-1.25.26011923.dist-info/RECORD +0 -7
- {sql_blocks-1.25.26011923.dist-info → sql_blocks-1.25.30011644.dist-info}/LICENSE +0 -0
- {sql_blocks-1.25.26011923.dist-info → sql_blocks-1.25.30011644.dist-info}/WHEEL +0 -0
- {sql_blocks-1.25.26011923.dist-info → sql_blocks-1.25.30011644.dist-info}/top_level.txt +0 -0
sql_blocks/sql_blocks.py
CHANGED
@@ -42,17 +42,23 @@ class SQLObject:
|
|
42
42
|
if not table_name:
|
43
43
|
return
|
44
44
|
cls = SQLObject
|
45
|
+
is_file_name = any([
|
46
|
+
'/' in table_name, '.' in table_name
|
47
|
+
])
|
48
|
+
ref = table_name
|
49
|
+
if is_file_name:
|
50
|
+
ref = table_name.split('/')[-1].split('.')[0]
|
45
51
|
if cls.ALIAS_FUNC:
|
46
|
-
self.__alias = cls.ALIAS_FUNC(
|
52
|
+
self.__alias = cls.ALIAS_FUNC(ref)
|
47
53
|
elif ' ' in table_name.strip():
|
48
54
|
table_name, self.__alias = table_name.split()
|
49
|
-
elif '_' in
|
55
|
+
elif '_' in ref:
|
50
56
|
self.__alias = ''.join(
|
51
57
|
word[0].lower()
|
52
|
-
for word in
|
58
|
+
for word in ref.split('_')
|
53
59
|
)
|
54
60
|
else:
|
55
|
-
self.__alias =
|
61
|
+
self.__alias = ref.lower()[:3]
|
56
62
|
self.values.setdefault(FROM, []).append(f'{table_name} {self.alias}')
|
57
63
|
|
58
64
|
@property
|
@@ -423,23 +429,23 @@ class Position(Enum):
|
|
423
429
|
class Where:
|
424
430
|
prefix = ''
|
425
431
|
|
426
|
-
def __init__(self,
|
427
|
-
self.
|
432
|
+
def __init__(self, content: str):
|
433
|
+
self.content = content
|
428
434
|
|
429
435
|
@classmethod
|
430
436
|
def __constructor(cls, operator: str, value):
|
431
|
-
return cls(
|
437
|
+
return cls(f'{operator} {quoted(value)}')
|
432
438
|
|
433
439
|
@classmethod
|
434
440
|
def eq(cls, value):
|
435
441
|
return cls.__constructor('=', value)
|
436
442
|
|
437
443
|
@classmethod
|
438
|
-
def contains(cls,
|
444
|
+
def contains(cls, text: str, pos: Position = Position.Middle):
|
439
445
|
return cls(
|
440
446
|
"LIKE '{}{}{}'".format(
|
441
447
|
'%' if pos != Position.StartsWith else '',
|
442
|
-
|
448
|
+
text,
|
443
449
|
'%' if pos != Position.EndsWith else ''
|
444
450
|
)
|
445
451
|
)
|
@@ -472,15 +478,33 @@ class Where:
|
|
472
478
|
|
473
479
|
@classmethod
|
474
480
|
def formula(cls, formula: str):
|
475
|
-
|
481
|
+
where = cls( ExpressionField(formula) )
|
482
|
+
where.add = where.add_expression
|
483
|
+
return where
|
484
|
+
|
485
|
+
def add_expression(self, name: str, main: SQLObject):
|
486
|
+
self.content = self.content.format(name, main)
|
487
|
+
main.values.setdefault(WHERE, []).append('{} {}'.format(
|
488
|
+
self.prefix, self.content
|
489
|
+
))
|
490
|
+
|
491
|
+
@classmethod
|
492
|
+
def join(cls, query: SQLObject):
|
493
|
+
where = cls(query)
|
494
|
+
where.add = where.add_join
|
495
|
+
return where
|
496
|
+
|
497
|
+
def add_join(self, name: str, main: SQLObject):
|
498
|
+
query = self.content
|
499
|
+
main.values[FROM].append(f',{query.table_name} {query.alias}')
|
500
|
+
for key in USUAL_KEYS:
|
501
|
+
main.update_values(key, query.values.get(key, []))
|
502
|
+
main.values.setdefault(WHERE, []).append('({a1}.{f1} = {a2}.{f2})'.format(
|
503
|
+
a1=main.alias, f1=name,
|
504
|
+
a2=query.alias, f2=query.key_field
|
505
|
+
))
|
476
506
|
|
477
507
|
def add(self, name: str, main: SQLObject):
|
478
|
-
if isinstance(self.expr, ExpressionField):
|
479
|
-
self.expr = self.expr.format(name, main)
|
480
|
-
main.values.setdefault(WHERE, []).append('{} {}'.format(
|
481
|
-
self.prefix, self.expr
|
482
|
-
))
|
483
|
-
return
|
484
508
|
func_type = FUNCTION_CLASS.get(name.lower())
|
485
509
|
exists = any(
|
486
510
|
main.is_named_field(fld, SELECT)
|
@@ -492,7 +516,7 @@ class Where:
|
|
492
516
|
elif not exists:
|
493
517
|
name = Field.format(name, main)
|
494
518
|
main.values.setdefault(WHERE, []).append('{}{} {}'.format(
|
495
|
-
self.prefix, name, self.
|
519
|
+
self.prefix, name, self.content
|
496
520
|
))
|
497
521
|
|
498
522
|
|
@@ -500,6 +524,10 @@ eq, contains, gt, gte, lt, lte, is_null, inside = (
|
|
500
524
|
getattr(Where, method) for method in
|
501
525
|
('eq', 'contains', 'gt', 'gte', 'lt', 'lte', 'is_null', 'inside')
|
502
526
|
)
|
527
|
+
startswith, endswith = [
|
528
|
+
lambda x: contains(x, Position.StartsWith),
|
529
|
+
lambda x: contains(x, Position.EndsWith)
|
530
|
+
]
|
503
531
|
|
504
532
|
|
505
533
|
class Not(Where):
|
@@ -507,7 +535,7 @@ class Not(Where):
|
|
507
535
|
|
508
536
|
@classmethod
|
509
537
|
def eq(cls, value):
|
510
|
-
return Where(
|
538
|
+
return Where(f'<> {quoted(value)}')
|
511
539
|
|
512
540
|
|
513
541
|
class Case:
|
@@ -548,7 +576,7 @@ class Options:
|
|
548
576
|
child: Where
|
549
577
|
for field, child in self.__children.items():
|
550
578
|
conditions.append(' {} {} '.format(
|
551
|
-
Field.format(field, main), child.
|
579
|
+
Field.format(field, main), child.content
|
552
580
|
))
|
553
581
|
main.values.setdefault(WHERE, []).append(
|
554
582
|
'(' + logical_separator.join(conditions) + ')'
|
@@ -647,7 +675,7 @@ class Having:
|
|
647
675
|
|
648
676
|
def add(self, name: str, main:SQLObject):
|
649
677
|
main.values[GROUP_BY][-1] += ' HAVING {} {}'.format(
|
650
|
-
self.function.format(name, main), self.condition.
|
678
|
+
self.function.format(name, main), self.condition.content
|
651
679
|
)
|
652
680
|
|
653
681
|
@classmethod
|
@@ -1451,11 +1479,11 @@ class CTE:
|
|
1451
1479
|
return '\n\t'.join(result)
|
1452
1480
|
|
1453
1481
|
def __str__(self) -> str:
|
1454
|
-
return 'WITH {}{} AS (\n\t{}\n)SELECT * FROM {}'.format(
|
1455
|
-
self.prefix, self.name,
|
1456
|
-
'\nUNION ALL\n\t'.join(
|
1482
|
+
return 'WITH {prefix}{name} AS (\n\t{queries}\n)SELECT * FROM {name}'.format(
|
1483
|
+
prefix=self.prefix, name=self.name,
|
1484
|
+
queries='\nUNION ALL\n\t'.join(
|
1457
1485
|
self.format(q) for q in self.query_list
|
1458
|
-
)
|
1486
|
+
)
|
1459
1487
|
)
|
1460
1488
|
|
1461
1489
|
class Recursive(CTE):
|
@@ -1584,7 +1612,7 @@ def parser_class(text: str) -> Parser:
|
|
1584
1612
|
return None
|
1585
1613
|
|
1586
1614
|
|
1587
|
-
def detect(text: str, join_queries: bool = True) -> Select:
|
1615
|
+
def detect(text: str, join_queries: bool = True) -> Select | list[Select]:
|
1588
1616
|
from collections import Counter
|
1589
1617
|
parser = parser_class(text)
|
1590
1618
|
if not parser:
|
@@ -1607,15 +1635,3 @@ def detect(text: str, join_queries: bool = True) -> Select:
|
|
1607
1635
|
result += query
|
1608
1636
|
return result
|
1609
1637
|
|
1610
|
-
|
1611
|
-
if __name__ == "__main__":
|
1612
|
-
MY_NAME = 'Júlio Cascalles'
|
1613
|
-
# query = Select('SocialMedia s', post=Count, reaction=Sum, user=GroupBy)
|
1614
|
-
# print( CTE('Metrics', [query]) )
|
1615
|
-
q1 = Select(
|
1616
|
-
'SocialMedia me', name=[ eq(MY_NAME), Field ]
|
1617
|
-
)
|
1618
|
-
q2 = Select(
|
1619
|
-
'SocialMedia you', name=Field, id=Where.formula('{af} = n.friend')
|
1620
|
-
)
|
1621
|
-
print( Recursive('Network', [q1, q2]) )
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sql_blocks
|
3
|
-
Version: 1.25.
|
3
|
+
Version: 1.25.30011644
|
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
|
@@ -153,6 +153,35 @@ FROM
|
|
153
153
|
JOIN Cast c ON (a.cast = c.id)
|
154
154
|
```
|
155
155
|
|
156
|
+
---
|
157
|
+
**5.1 Multiple tables without JOIN**
|
158
|
+
> Warning: This is **NOT** recommended! ⛔
|
159
|
+
|
160
|
+
|
161
|
+
#### Example:
|
162
|
+
singer = Select(
|
163
|
+
"Singer artist", id=PrimaryKey,
|
164
|
+
name=NamedField('artist_name')
|
165
|
+
)
|
166
|
+
album = Select (
|
167
|
+
"Album album",
|
168
|
+
name=NamedField('album_name'),
|
169
|
+
artist_id=Where.join(singer), # <===== 👀
|
170
|
+
)
|
171
|
+
**>> print(query)**
|
172
|
+
|
173
|
+
SELECT
|
174
|
+
album.name as album_name,
|
175
|
+
artist.name as artist_name,
|
176
|
+
album.year_recorded
|
177
|
+
FROM
|
178
|
+
'sql_blocks/music/data/Album.csv' album
|
179
|
+
,'sql_blocks/music/data/Singer.csv' artist
|
180
|
+
WHERE
|
181
|
+
(album.artist_id = artist.id)
|
182
|
+
|
183
|
+
|
184
|
+
|
156
185
|
---
|
157
186
|
### 6 - The reverse process (parse):
|
158
187
|
```
|
@@ -0,0 +1,7 @@
|
|
1
|
+
sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
|
2
|
+
sql_blocks/sql_blocks.py,sha256=2R4VoSZUHTb1gSZwKjtNfkjxeH8G1dKYuDpuKv-UP7E,54430
|
3
|
+
sql_blocks-1.25.30011644.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
4
|
+
sql_blocks-1.25.30011644.dist-info/METADATA,sha256=2Q1naQygxXqw87DTc70LyLjs8uWK95v0CWu5B9qHLlQ,16884
|
5
|
+
sql_blocks-1.25.30011644.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
+
sql_blocks-1.25.30011644.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
|
7
|
+
sql_blocks-1.25.30011644.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
1
|
-
sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
|
2
|
-
sql_blocks/sql_blocks.py,sha256=lVV1Z09JVmwvV0vzKqZVBHpGWpZefD1RsMZy-aIJZSk,53868
|
3
|
-
sql_blocks-1.25.26011923.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
4
|
-
sql_blocks-1.25.26011923.dist-info/METADATA,sha256=qvFr99uB0b95uv7MqpvpZaMrH7VrE557bmW4YWFQgnA,16187
|
5
|
-
sql_blocks-1.25.26011923.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
-
sql_blocks-1.25.26011923.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
|
7
|
-
sql_blocks-1.25.26011923.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|