sql-blocks 0.2.0__tar.gz → 0.2.2__tar.gz
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-0.2.0/sql_blocks.egg-info → sql_blocks-0.2.2}/PKG-INFO +11 -9
- {sql_blocks-0.2.0 → sql_blocks-0.2.2}/README.md +10 -8
- {sql_blocks-0.2.0 → sql_blocks-0.2.2}/pyproject.toml +1 -1
- {sql_blocks-0.2.0 → sql_blocks-0.2.2}/setup.py +1 -1
- {sql_blocks-0.2.0 → sql_blocks-0.2.2}/sql_blocks/sql_blocks.py +28 -25
- {sql_blocks-0.2.0 → sql_blocks-0.2.2/sql_blocks.egg-info}/PKG-INFO +11 -9
- {sql_blocks-0.2.0 → sql_blocks-0.2.2}/LICENSE +0 -0
- {sql_blocks-0.2.0 → sql_blocks-0.2.2}/setup.cfg +0 -0
- {sql_blocks-0.2.0 → sql_blocks-0.2.2}/sql_blocks/__init__.py +0 -0
- {sql_blocks-0.2.0 → sql_blocks-0.2.2}/sql_blocks.egg-info/SOURCES.txt +0 -0
- {sql_blocks-0.2.0 → sql_blocks-0.2.2}/sql_blocks.egg-info/dependency_links.txt +0 -0
- {sql_blocks-0.2.0 → sql_blocks-0.2.2}/sql_blocks.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sql_blocks
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.2
|
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
|
@@ -24,7 +24,7 @@ _Note that an alias "act" has been added._
|
|
24
24
|
You can specify your own alias: `a = Select('Actor a')`
|
25
25
|
|
26
26
|
---
|
27
|
-
### 2 - You can also add a field,
|
27
|
+
### 2 - You can also add a field, contains this...
|
28
28
|
|
29
29
|
* a = Select('Actor a', **name=Field**)
|
30
30
|
|
@@ -62,11 +62,13 @@ You can specify your own alias: `a = Select('Actor a')`
|
|
62
62
|
* field=gt(value) - ...the field is GREATER than the value;
|
63
63
|
* field=lt(value) - ...the field is LESS than the value;
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
65
|
+
> You may use Where.**eq**, Where.**gt**, Where.**lt** ... or simply **eq**, **gt**, **lt** ... 😉
|
66
|
+
|
67
|
+
3.1 -- If you want to filter the field on a range of values:
|
68
|
+
|
69
|
+
`a = Select( 'Actor a', age=Between(45, 69) )`
|
68
70
|
|
69
|
-
|
71
|
+
3.2 -- Sub-queries:
|
70
72
|
```
|
71
73
|
query = Select('Movie m', title=Field,
|
72
74
|
id=SelectIN(
|
@@ -93,7 +95,7 @@ query = Select('Movie m', title=Field,
|
|
93
95
|
```
|
94
96
|
OR=Options(
|
95
97
|
genre=eq("Sci-Fi"),
|
96
|
-
awards=
|
98
|
+
awards=contains("Oscar")
|
97
99
|
)
|
98
100
|
```
|
99
101
|
> Could be AND=Options(...)
|
@@ -105,7 +107,7 @@ based_on_book=Not.is_null()
|
|
105
107
|
|
106
108
|
3.5 -- List of values
|
107
109
|
```
|
108
|
-
hash_tag=
|
110
|
+
hash_tag=inside(['space', 'monster', 'gore'])
|
109
111
|
```
|
110
112
|
|
111
113
|
---
|
@@ -113,7 +115,7 @@ hash_tag=contains(['space', 'monster', 'gore'])
|
|
113
115
|
|
114
116
|
* m = Select('Movie m' release_date=[Field, OrderBy])
|
115
117
|
- This means that the field will appear in the results and also that the query will be ordered by that field.
|
116
|
-
* Applying **GROUP BY** to item 3.2, it would look
|
118
|
+
* Applying **GROUP BY** to item 3.2, it would look contains this:
|
117
119
|
```
|
118
120
|
SelectIN(
|
119
121
|
'Review r', movie=[GroupBy, Distinct],
|
@@ -9,7 +9,7 @@ _Note that an alias "act" has been added._
|
|
9
9
|
You can specify your own alias: `a = Select('Actor a')`
|
10
10
|
|
11
11
|
---
|
12
|
-
### 2 - You can also add a field,
|
12
|
+
### 2 - You can also add a field, contains this...
|
13
13
|
|
14
14
|
* a = Select('Actor a', **name=Field**)
|
15
15
|
|
@@ -47,11 +47,13 @@ You can specify your own alias: `a = Select('Actor a')`
|
|
47
47
|
* field=gt(value) - ...the field is GREATER than the value;
|
48
48
|
* field=lt(value) - ...the field is LESS than the value;
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
> You may use Where.**eq**, Where.**gt**, Where.**lt** ... or simply **eq**, **gt**, **lt** ... 😉
|
51
|
+
|
52
|
+
3.1 -- If you want to filter the field on a range of values:
|
53
|
+
|
54
|
+
`a = Select( 'Actor a', age=Between(45, 69) )`
|
53
55
|
|
54
|
-
|
56
|
+
3.2 -- Sub-queries:
|
55
57
|
```
|
56
58
|
query = Select('Movie m', title=Field,
|
57
59
|
id=SelectIN(
|
@@ -78,7 +80,7 @@ query = Select('Movie m', title=Field,
|
|
78
80
|
```
|
79
81
|
OR=Options(
|
80
82
|
genre=eq("Sci-Fi"),
|
81
|
-
awards=
|
83
|
+
awards=contains("Oscar")
|
82
84
|
)
|
83
85
|
```
|
84
86
|
> Could be AND=Options(...)
|
@@ -90,7 +92,7 @@ based_on_book=Not.is_null()
|
|
90
92
|
|
91
93
|
3.5 -- List of values
|
92
94
|
```
|
93
|
-
hash_tag=
|
95
|
+
hash_tag=inside(['space', 'monster', 'gore'])
|
94
96
|
```
|
95
97
|
|
96
98
|
---
|
@@ -98,7 +100,7 @@ hash_tag=contains(['space', 'monster', 'gore'])
|
|
98
100
|
|
99
101
|
* m = Select('Movie m' release_date=[Field, OrderBy])
|
100
102
|
- This means that the field will appear in the results and also that the query will be ordered by that field.
|
101
|
-
* Applying **GROUP BY** to item 3.2, it would look
|
103
|
+
* Applying **GROUP BY** to item 3.2, it would look contains this:
|
102
104
|
```
|
103
105
|
SelectIN(
|
104
106
|
'Review r', movie=[GroupBy, Distinct],
|
@@ -4,15 +4,14 @@ import re
|
|
4
4
|
|
5
5
|
PATTERN_PREFIX = '([^0-9 ]+[.])'
|
6
6
|
PATTERN_SUFFIX = '( [A-Za-z_]+)'
|
7
|
-
|
8
|
-
DISTINCT_PREFX = f'(DISTINCT|distinct)|{PATTERN_PREFIX}'
|
7
|
+
DISTINCT_PREFX = '(DISTINCT|distinct)'
|
9
8
|
|
10
9
|
KEYWORD = {
|
11
10
|
'SELECT': (',{}', 'SELECT *', DISTINCT_PREFX),
|
12
11
|
'FROM': ('{}', '', PATTERN_SUFFIX),
|
13
12
|
'WHERE': ('{}AND ', '', ''),
|
14
|
-
'GROUP BY': (',{}', '',
|
15
|
-
'ORDER BY': (',{}', '',
|
13
|
+
'GROUP BY': (',{}', '', PATTERN_SUFFIX),
|
14
|
+
'ORDER BY': (',{}', '', PATTERN_SUFFIX),
|
16
15
|
'LIMIT': (' ', '', ''),
|
17
16
|
}
|
18
17
|
# ^ ^ ^
|
@@ -69,16 +68,18 @@ class SQLObject:
|
|
69
68
|
appendix = {WHERE: 'and|', FROM: 'join|JOIN'}
|
70
69
|
return KEYWORD[key][0].format(appendix.get(key, ''))
|
71
70
|
|
72
|
-
def diff(self, key: str, search_list: list,
|
71
|
+
def diff(self, key: str, search_list: list, exact: bool=False) -> set:
|
73
72
|
def cleanup(fld: str) -> str:
|
74
|
-
if
|
73
|
+
if exact:
|
75
74
|
fld = fld.lower()
|
76
75
|
return fld.strip()
|
77
76
|
def is_named_field(fld: str) -> bool:
|
78
77
|
return key == SELECT and re.search(' as | AS ', fld)
|
79
78
|
pattern = KEYWORD[key][2]
|
80
|
-
if
|
81
|
-
|
79
|
+
if exact:
|
80
|
+
if key == WHERE:
|
81
|
+
pattern = ' '
|
82
|
+
pattern += f'|{PATTERN_PREFIX}'
|
82
83
|
separator = self.get_separator(key)
|
83
84
|
def field_set(source: list) -> set:
|
84
85
|
return set(
|
@@ -91,7 +92,7 @@ class SQLObject:
|
|
91
92
|
)
|
92
93
|
s1 = field_set(search_list)
|
93
94
|
s2 = field_set(self.values.get(key, []))
|
94
|
-
if
|
95
|
+
if exact:
|
95
96
|
return s1.symmetric_difference(s2)
|
96
97
|
return s1 - s2
|
97
98
|
|
@@ -247,7 +248,7 @@ class Where:
|
|
247
248
|
return cls.__constructor('=', value)
|
248
249
|
|
249
250
|
@classmethod
|
250
|
-
def
|
251
|
+
def contains(cls, value: str):
|
251
252
|
return cls(f"LIKE '%{value}%'")
|
252
253
|
|
253
254
|
@classmethod
|
@@ -271,7 +272,7 @@ class Where:
|
|
271
272
|
return cls('IS NULL')
|
272
273
|
|
273
274
|
@classmethod
|
274
|
-
def
|
275
|
+
def inside(cls, values):
|
275
276
|
if isinstance(values, list):
|
276
277
|
values = ','.join(quoted(v) for v in values)
|
277
278
|
return cls(f'IN ({values})')
|
@@ -282,9 +283,9 @@ class Where:
|
|
282
283
|
))
|
283
284
|
|
284
285
|
|
285
|
-
eq,
|
286
|
+
eq, contains, gt, gte, lt, lte, is_null, inside = (
|
286
287
|
getattr(Where, method) for method in
|
287
|
-
('eq', '
|
288
|
+
('eq', 'contains', 'gt', 'gte', 'lt', 'lte', 'is_null', 'inside')
|
288
289
|
)
|
289
290
|
|
290
291
|
|
@@ -447,23 +448,25 @@ class Select(SQLObject):
|
|
447
448
|
main.update_values(key, self.values.get(key, []))
|
448
449
|
|
449
450
|
def __add__(self, other: SQLObject):
|
450
|
-
|
451
|
+
from copy import deepcopy
|
452
|
+
query = deepcopy(self)
|
453
|
+
if query.table_name.lower() == other.table_name.lower():
|
451
454
|
for key in USUAL_KEYS:
|
452
|
-
|
453
|
-
return
|
454
|
-
foreign_field, primary_key = ForeignKey.find(
|
455
|
+
query.update_values(key, other.values.get(key, []))
|
456
|
+
return query
|
457
|
+
foreign_field, primary_key = ForeignKey.find(query, other)
|
455
458
|
if not foreign_field:
|
456
|
-
foreign_field, primary_key = ForeignKey.find(other,
|
459
|
+
foreign_field, primary_key = ForeignKey.find(other, query)
|
457
460
|
if foreign_field:
|
458
461
|
if primary_key:
|
459
|
-
PrimaryKey.add(primary_key,
|
460
|
-
|
462
|
+
PrimaryKey.add(primary_key, query)
|
463
|
+
query.add(foreign_field, other)
|
461
464
|
return other
|
462
|
-
raise ValueError(f'No relationship found between {
|
465
|
+
raise ValueError(f'No relationship found between {query.table_name} and {other.table_name}.')
|
463
466
|
elif primary_key:
|
464
467
|
PrimaryKey.add(primary_key, other)
|
465
|
-
other.add(foreign_field,
|
466
|
-
return
|
468
|
+
other.add(foreign_field, query)
|
469
|
+
return query
|
467
470
|
|
468
471
|
def __str__(self) -> str:
|
469
472
|
TABULATION = '\n\t' if self.break_lines else ' '
|
@@ -590,7 +593,7 @@ class SelectIN(Select):
|
|
590
593
|
|
591
594
|
def add(self, name: str, main: SQLObject):
|
592
595
|
self.break_lines = False
|
593
|
-
self.condition_class.
|
596
|
+
self.condition_class.inside(self).add(name, main)
|
594
597
|
|
595
598
|
SubSelect = SelectIN
|
596
599
|
|
@@ -644,7 +647,7 @@ class RuleLogicalOp(Rule):
|
|
644
647
|
))
|
645
648
|
for i, condition in enumerate(target.values.get(WHERE, [])):
|
646
649
|
expr = re.sub('\n|\t', ' ', condition)
|
647
|
-
if not re.search(r'\b(NOT|not)
|
650
|
+
if not re.search(r'\b(NOT|not).*[<>=]', expr):
|
648
651
|
continue
|
649
652
|
tokens = [t.strip() for t in re.split(r'NOT\b|not\b|(<|>|=)', expr) if t]
|
650
653
|
op = ''.join(tokens[1: len(tokens)-1])
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sql_blocks
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.2
|
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
|
@@ -24,7 +24,7 @@ _Note that an alias "act" has been added._
|
|
24
24
|
You can specify your own alias: `a = Select('Actor a')`
|
25
25
|
|
26
26
|
---
|
27
|
-
### 2 - You can also add a field,
|
27
|
+
### 2 - You can also add a field, contains this...
|
28
28
|
|
29
29
|
* a = Select('Actor a', **name=Field**)
|
30
30
|
|
@@ -62,11 +62,13 @@ You can specify your own alias: `a = Select('Actor a')`
|
|
62
62
|
* field=gt(value) - ...the field is GREATER than the value;
|
63
63
|
* field=lt(value) - ...the field is LESS than the value;
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
65
|
+
> You may use Where.**eq**, Where.**gt**, Where.**lt** ... or simply **eq**, **gt**, **lt** ... 😉
|
66
|
+
|
67
|
+
3.1 -- If you want to filter the field on a range of values:
|
68
|
+
|
69
|
+
`a = Select( 'Actor a', age=Between(45, 69) )`
|
68
70
|
|
69
|
-
|
71
|
+
3.2 -- Sub-queries:
|
70
72
|
```
|
71
73
|
query = Select('Movie m', title=Field,
|
72
74
|
id=SelectIN(
|
@@ -93,7 +95,7 @@ query = Select('Movie m', title=Field,
|
|
93
95
|
```
|
94
96
|
OR=Options(
|
95
97
|
genre=eq("Sci-Fi"),
|
96
|
-
awards=
|
98
|
+
awards=contains("Oscar")
|
97
99
|
)
|
98
100
|
```
|
99
101
|
> Could be AND=Options(...)
|
@@ -105,7 +107,7 @@ based_on_book=Not.is_null()
|
|
105
107
|
|
106
108
|
3.5 -- List of values
|
107
109
|
```
|
108
|
-
hash_tag=
|
110
|
+
hash_tag=inside(['space', 'monster', 'gore'])
|
109
111
|
```
|
110
112
|
|
111
113
|
---
|
@@ -113,7 +115,7 @@ hash_tag=contains(['space', 'monster', 'gore'])
|
|
113
115
|
|
114
116
|
* m = Select('Movie m' release_date=[Field, OrderBy])
|
115
117
|
- This means that the field will appear in the results and also that the query will be ordered by that field.
|
116
|
-
* Applying **GROUP BY** to item 3.2, it would look
|
118
|
+
* Applying **GROUP BY** to item 3.2, it would look contains this:
|
117
119
|
```
|
118
120
|
SelectIN(
|
119
121
|
'Review r', movie=[GroupBy, Distinct],
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|