sql-blocks 0.0.4__py3-none-any.whl → 0.0.6__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/__init__.py +1 -1
- sql_blocks/sql_blocks.py +55 -53
- {sql_blocks-0.0.4.dist-info → sql_blocks-0.0.6.dist-info}/METADATA +5 -5
- sql_blocks-0.0.6.dist-info/RECORD +7 -0
- sql_blocks-0.0.4.dist-info/RECORD +0 -7
- {sql_blocks-0.0.4.dist-info → sql_blocks-0.0.6.dist-info}/LICENSE +0 -0
- {sql_blocks-0.0.4.dist-info → sql_blocks-0.0.6.dist-info}/WHEEL +0 -0
- {sql_blocks-0.0.4.dist-info → sql_blocks-0.0.6.dist-info}/top_level.txt +0 -0
sql_blocks/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
from sql_blocks import *
|
1
|
+
from sql_blocks.sql_blocks import *
|
sql_blocks/sql_blocks.py
CHANGED
@@ -2,14 +2,27 @@ from enum import Enum
|
|
2
2
|
import re
|
3
3
|
|
4
4
|
|
5
|
+
PATTERN_PREFIX = '([^0-9 ]+[.])'
|
6
|
+
PATTERN_SUFFIX = '( [A-Za-z_]+)'
|
7
|
+
SUFFIX_AND_PRE = f'{PATTERN_SUFFIX}|{PATTERN_PREFIX}'
|
8
|
+
DISTINCT_SF_PR = f'(DISTINCT|distinct)|{SUFFIX_AND_PRE}'
|
9
|
+
|
5
10
|
KEYWORD = {
|
6
|
-
'SELECT': (',{}', 'SELECT *'),
|
7
|
-
'FROM': ('{}', ''),
|
8
|
-
'WHERE': ('{}AND ', ''),
|
9
|
-
'GROUP BY': (',{}', ''),
|
10
|
-
'ORDER BY': (',{}', ''),
|
11
|
-
'LIMIT': (' ', ''),
|
11
|
+
'SELECT': (',{}', 'SELECT *', DISTINCT_SF_PR),
|
12
|
+
'FROM': ('{}', '', PATTERN_SUFFIX),
|
13
|
+
'WHERE': ('{}AND ', '', PATTERN_PREFIX),
|
14
|
+
'GROUP BY': (',{}', '', SUFFIX_AND_PRE),
|
15
|
+
'ORDER BY': (',{}', '', SUFFIX_AND_PRE),
|
16
|
+
'LIMIT': (' ', '', ''),
|
12
17
|
}
|
18
|
+
# ^ ^ ^
|
19
|
+
# | | |
|
20
|
+
# | | +----- pattern to compare fields
|
21
|
+
# | |
|
22
|
+
# | +----- default when empty (SELECT * ...)
|
23
|
+
# |
|
24
|
+
# +-------- separator
|
25
|
+
|
13
26
|
SELECT, FROM, WHERE, GROUP_BY, ORDER_BY, LIMIT = KEYWORD.keys()
|
14
27
|
USUAL_KEYS = [SELECT, WHERE, GROUP_BY, ORDER_BY]
|
15
28
|
|
@@ -39,6 +52,26 @@ class SQLObject:
|
|
39
52
|
def table_name(self) -> str:
|
40
53
|
return self.values[FROM][0].split()[0]
|
41
54
|
|
55
|
+
@staticmethod
|
56
|
+
def get_separator(key: str) -> str:
|
57
|
+
appendix = {WHERE: 'and|', FROM: 'join|JOIN'}
|
58
|
+
return KEYWORD[key][0].format(appendix.get(key, ''))
|
59
|
+
|
60
|
+
def diff(self, key: str, search_list: list, symmetrical: bool=False) -> set:
|
61
|
+
pattern = KEYWORD[key][2]
|
62
|
+
separator = self.get_separator(key)
|
63
|
+
def field_set(source: list) -> set:
|
64
|
+
return set(
|
65
|
+
re.sub(pattern, '', fld.strip()).lower()
|
66
|
+
for string in source
|
67
|
+
for fld in re.split(separator, string)
|
68
|
+
)
|
69
|
+
s1 = field_set(search_list)
|
70
|
+
s2 = field_set(self.values.get(key, []))
|
71
|
+
if symmetrical:
|
72
|
+
return s1.symmetric_difference(s2)
|
73
|
+
return s1 - s2
|
74
|
+
|
42
75
|
def delete(self, search: str, keys: list=USUAL_KEYS):
|
43
76
|
for key in keys:
|
44
77
|
result = []
|
@@ -329,13 +362,12 @@ class Select(SQLObject):
|
|
329
362
|
self.__call__(**values)
|
330
363
|
self.break_lines = True
|
331
364
|
|
365
|
+
def update_values(self, key: str, new_values: list):
|
366
|
+
for value in self.diff(key, new_values):
|
367
|
+
self.values.setdefault(key, []).append(value)
|
368
|
+
|
332
369
|
def add(self, name: str, main: SQLObject):
|
333
|
-
|
334
|
-
for value in new_values:
|
335
|
-
old_values = main.values.get(key, [])
|
336
|
-
if value not in old_values:
|
337
|
-
main.values[key] = old_values + [value]
|
338
|
-
update_values(
|
370
|
+
main.update_values(
|
339
371
|
FROM, [
|
340
372
|
'{jt}JOIN {tb} {a2} ON ({a1}.{f1} = {a2}.{f2})'.format(
|
341
373
|
jt=self.join_type.value,
|
@@ -346,9 +378,13 @@ class Select(SQLObject):
|
|
346
378
|
] + self.values[FROM][1:]
|
347
379
|
)
|
348
380
|
for key in USUAL_KEYS:
|
349
|
-
update_values(key, self.values.get(key, []))
|
381
|
+
main.update_values(key, self.values.get(key, []))
|
350
382
|
|
351
383
|
def __add__(self, other: SQLObject):
|
384
|
+
if self.table_name.lower() == other.table_name.lower():
|
385
|
+
for key in USUAL_KEYS:
|
386
|
+
self.update_values(key, other.values.get(key, []))
|
387
|
+
return self
|
352
388
|
foreign_field, primary_key = ForeignKey.find(self, other)
|
353
389
|
if not foreign_field:
|
354
390
|
foreign_field, primary_key = ForeignKey.find(other, self)
|
@@ -383,10 +419,8 @@ class Select(SQLObject):
|
|
383
419
|
return self
|
384
420
|
|
385
421
|
def __eq__(self, other: SQLObject) -> bool:
|
386
|
-
def sorted_values(obj: SQLObject, key: str) -> list:
|
387
|
-
return sorted(obj.values.get(key, []))
|
388
422
|
for key in KEYWORD:
|
389
|
-
if
|
423
|
+
if self.diff(key, other.values.get(key, []), True):
|
390
424
|
return False
|
391
425
|
return True
|
392
426
|
|
@@ -427,7 +461,7 @@ class Select(SQLObject):
|
|
427
461
|
inner = txt[start: end]
|
428
462
|
if inner.count('(') > inner.count(')'):
|
429
463
|
end = find_parenthesis(end)
|
430
|
-
inner = txt[start: end]
|
464
|
+
inner = txt[start: end-1]
|
431
465
|
fld, *inner = re.split(r' IN | in', inner, maxsplit=1)
|
432
466
|
if fld.upper() == 'NOT':
|
433
467
|
pos = find_last_word(start)
|
@@ -457,15 +491,12 @@ class Select(SQLObject):
|
|
457
491
|
for key in USUAL_KEYS:
|
458
492
|
if not key in values:
|
459
493
|
continue
|
460
|
-
separator =
|
461
|
-
|
494
|
+
separator = cls.get_separator(key)
|
495
|
+
obj.values[key] = [
|
462
496
|
Field.format(fld, obj)
|
463
|
-
for fld in re.split(
|
464
|
-
|
465
|
-
) if len(tables) == 1
|
466
|
-
or re.findall(f'\b*{obj.alias}[.]', fld)
|
497
|
+
for fld in re.split(separator, values[key])
|
498
|
+
if len(tables) == 1 or re.findall(f'\b*{obj.alias}[.]', fld)
|
467
499
|
]
|
468
|
-
obj.values[key] = [ f for f in fields if f.strip() ]
|
469
500
|
result[obj.alias] = obj
|
470
501
|
return list( result.values() )
|
471
502
|
|
@@ -480,32 +511,3 @@ SubSelect = SelectIN
|
|
480
511
|
|
481
512
|
class NotSelectIN(SelectIN):
|
482
513
|
condition_class = Not
|
483
|
-
|
484
|
-
|
485
|
-
if __name__ == "__main__":
|
486
|
-
query_list = Select.parse("""
|
487
|
-
SELECT
|
488
|
-
cas.role,
|
489
|
-
m.title,
|
490
|
-
m.release_date,
|
491
|
-
a.name as actors_name
|
492
|
-
FROM
|
493
|
-
Actor a
|
494
|
-
LEFT JOIN Cast cas ON (a.cast = cas.id)
|
495
|
-
LEFT JOIN Movie m ON (cas.movie = m.id)
|
496
|
-
WHERE
|
497
|
-
m.genre NOT in (SELECT g.id from Genres g where g.name in ('sci-fi', 'horror', 'distopia'))
|
498
|
-
AND (m.hashtag = '#cult' OR m.awards LIKE '%Oscar%')
|
499
|
-
AND m.id IN (select DISTINCT r.movie FROM Review r GROUP BY r.movie HAVING Avg(r.rate) > 4.5)
|
500
|
-
AND a.age <= 69 AND a.age >= 45
|
501
|
-
ORDER BY
|
502
|
-
m.release_date
|
503
|
-
""")
|
504
|
-
for query in query_list:
|
505
|
-
descr = ' {} ({}) '.format(
|
506
|
-
query.table_name,
|
507
|
-
query.__class__.__name__
|
508
|
-
)
|
509
|
-
print(descr.center(50, '-'))
|
510
|
-
print(query)
|
511
|
-
print('='*50)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sql_blocks
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.6
|
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
|
@@ -249,13 +249,13 @@ m = Select...
|
|
249
249
|
9.1
|
250
250
|
```
|
251
251
|
a1 = Select.parse('''
|
252
|
-
SELECT gender,
|
252
|
+
SELECT gender, Max(act.age) FROM Actor act
|
253
253
|
WHERE act.age <= 69 AND act.age >= 45
|
254
254
|
GROUP BY gender
|
255
255
|
''')[0]
|
256
256
|
|
257
257
|
a2 = Select('Actor',
|
258
|
-
age=Between(45, 69),
|
258
|
+
age=[ Between(45, 69), Max ],
|
259
259
|
gender=[GroupBy, Field]
|
260
260
|
)
|
261
261
|
```
|
@@ -306,9 +306,9 @@ m2 = Select(
|
|
306
306
|
Select(
|
307
307
|
'Product',
|
308
308
|
label=Case('price').when(
|
309
|
-
lt(50), 'cheap'
|
309
|
+
Where.lt(50), 'cheap'
|
310
310
|
).when(
|
311
|
-
gt(100), 'expensive'
|
311
|
+
Where.gt(100), 'expensive'
|
312
312
|
).else_value(
|
313
313
|
'normal'
|
314
314
|
)
|
@@ -0,0 +1,7 @@
|
|
1
|
+
sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
|
2
|
+
sql_blocks/sql_blocks.py,sha256=Fs636uSwXTxlzHH9SCOxmGTgt2MjhQ6Pf6v92CRtQ9E,16229
|
3
|
+
sql_blocks-0.0.6.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
4
|
+
sql_blocks-0.0.6.dist-info/METADATA,sha256=-2-vPw1nkpqKvlp0l2Bt8VF_sBZ_TM8BGf-Nmk8X2oo,7037
|
5
|
+
sql_blocks-0.0.6.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
+
sql_blocks-0.0.6.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
|
7
|
+
sql_blocks-0.0.6.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
1
|
-
sql_blocks/__init__.py,sha256=TodC5q-UEdYEz9v1RRoogVqqRcsKnZRY1WDGinrI2zo,26
|
2
|
-
sql_blocks/sql_blocks.py,sha256=CX8rJtDvL07eGjwJbiqRKDckvrosJf4_PEBw5SK8mrQ,16051
|
3
|
-
sql_blocks-0.0.4.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
4
|
-
sql_blocks-0.0.4.dist-info/METADATA,sha256=RoaYK32YS_CAW2UBogLABwxIPPwjqcmZH1EQh-iA2ZQ,7028
|
5
|
-
sql_blocks-0.0.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
-
sql_blocks-0.0.4.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
|
7
|
-
sql_blocks-0.0.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|