sql-blocks 0.0.1__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.0.1/LICENSE +19 -0
- sql_blocks-0.0.1/PKG-INFO +296 -0
- sql_blocks-0.0.1/README.md +281 -0
- sql_blocks-0.0.1/pyproject.toml +17 -0
- sql_blocks-0.0.1/setup.cfg +4 -0
- sql_blocks-0.0.1/setup.py +19 -0
- sql_blocks-0.0.1/sql_blocks/__init__.py +1 -0
- sql_blocks-0.0.1/sql_blocks/sql_blocks.py +383 -0
- sql_blocks-0.0.1/sql_blocks.egg-info/PKG-INFO +296 -0
- sql_blocks-0.0.1/sql_blocks.egg-info/SOURCES.txt +11 -0
- sql_blocks-0.0.1/sql_blocks.egg-info/dependency_links.txt +1 -0
- sql_blocks-0.0.1/sql_blocks.egg-info/top_level.txt +1 -0
- sql_blocks-0.0.1/tests/tests.py +90 -0
sql_blocks-0.0.1/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2018 The Python Packaging Authority
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
@@ -0,0 +1,296 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: sql_blocks
|
3
|
+
Version: 0.0.1
|
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
|
+
Home-page: https://github.com/julio-cascalles/sql_blocks
|
6
|
+
Author: Júlio Cascalles
|
7
|
+
Author-email: Julio Cascalles <julio.cascalles@outlook.com>
|
8
|
+
Project-URL: Homepage, https://github.com/julio-cascalles/sql_blocks
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
11
|
+
Classifier: Operating System :: OS Independent
|
12
|
+
Requires-Python: >=3.8
|
13
|
+
Description-Content-Type: text/markdown
|
14
|
+
License-File: LICENSE
|
15
|
+
|
16
|
+
# SQL_Blocks
|
17
|
+
|
18
|
+
### 1 - You can assemble a simple object that will then be converted into an SQL command:
|
19
|
+
|
20
|
+
> a = Select('Actor') # --> SELECT * FROM Actor act
|
21
|
+
|
22
|
+
_Note that an alias "act" has been added._
|
23
|
+
|
24
|
+
You can specify your own alias: `a = Select('Actor a')`
|
25
|
+
|
26
|
+
---
|
27
|
+
### 2 - You can also add a field, like this...
|
28
|
+
|
29
|
+
* a = Select('Actor a', **name=Field**)
|
30
|
+
|
31
|
+
* Here are another ways to add a field:
|
32
|
+
- Select('Actor a', name=Distinct )
|
33
|
+
|
34
|
+
- Select('Actor a', name=NamedField('actors_name'))
|
35
|
+
|
36
|
+
- Select(
|
37
|
+
'Actor a',
|
38
|
+
name=NamedField('actors_name'), Distinct
|
39
|
+
)
|
40
|
+
|
41
|
+
---
|
42
|
+
|
43
|
+
### 3 - To set conditions, use **Where**:
|
44
|
+
* For example, `a = Select(... age=Where.gt(45) )`
|
45
|
+
|
46
|
+
Some possible conditions:
|
47
|
+
* field=Where.eq(value) - ...the field is EQUAL to the value;
|
48
|
+
* field=Where.gt(value) - ...the field is GREATER than the value;
|
49
|
+
* field=Where.lt(value) - ...the field is LESS than the value;
|
50
|
+
|
51
|
+
3.1 -- If you want to filter the field on a range of values:
|
52
|
+
|
53
|
+
`a = Select( 'Actor a', age=Between(45, 69) )`
|
54
|
+
|
55
|
+
3.2 -- Sub-queries:
|
56
|
+
|
57
|
+
```
|
58
|
+
query = Select('Movie m', title=Field,
|
59
|
+
id=SubSelect(
|
60
|
+
'Review r',
|
61
|
+
rate=Where.gt(4.5),
|
62
|
+
movie_id=Distinct
|
63
|
+
)
|
64
|
+
)
|
65
|
+
```
|
66
|
+
|
67
|
+
**>> print(query)**
|
68
|
+
|
69
|
+
SELECT
|
70
|
+
m.title
|
71
|
+
FROM
|
72
|
+
Movie m
|
73
|
+
WHERE
|
74
|
+
m.id IN (
|
75
|
+
SELECT DISTINCT r.movie
|
76
|
+
FROM Review r WHERE r.rate > 4.5
|
77
|
+
)
|
78
|
+
|
79
|
+
3.3 -- Optional conditions:
|
80
|
+
```
|
81
|
+
OR=Options(
|
82
|
+
genre=Where.eq("Sci-Fi"),
|
83
|
+
awards=Where.like("Oscar")
|
84
|
+
)
|
85
|
+
```
|
86
|
+
> Could be AND=Options(...)
|
87
|
+
|
88
|
+
---
|
89
|
+
### 4 - A field can be two things at the same time:
|
90
|
+
|
91
|
+
* m = Select('Movie m' release_date=[Field, OrderBy])
|
92
|
+
- This means that the field will appear in the results and also that the query will be ordered by that field.
|
93
|
+
* Applying **GROUP BY** to item 3.2, it would look like this:
|
94
|
+
```
|
95
|
+
SubSelect(
|
96
|
+
'Review r', movie=[GroupBy, Distinct],
|
97
|
+
rate=Having.avg(Where.gt(4.5))
|
98
|
+
)
|
99
|
+
```
|
100
|
+
---
|
101
|
+
### 5 - Relationships:
|
102
|
+
```
|
103
|
+
query = Select('Actor a', name=Field,
|
104
|
+
cast=Select('Cast c', id=PrimaryKey)
|
105
|
+
)
|
106
|
+
```
|
107
|
+
**>> print(query)**
|
108
|
+
```
|
109
|
+
SELECT
|
110
|
+
a.name
|
111
|
+
FROM
|
112
|
+
Actor a
|
113
|
+
JOIN Cast c ON (a.cast = c.id)
|
114
|
+
```
|
115
|
+
|
116
|
+
---
|
117
|
+
### 6 - The reverse process (parse):
|
118
|
+
```
|
119
|
+
text = """
|
120
|
+
SELECT
|
121
|
+
cas.role,
|
122
|
+
m.title,
|
123
|
+
m.release_date,
|
124
|
+
a.name as actors_name
|
125
|
+
FROM
|
126
|
+
Actor a
|
127
|
+
LEFT JOIN Cast cas ON (a.cast = cas.id)
|
128
|
+
LEFT JOIN Movie m ON (cas.movie = m.id)
|
129
|
+
WHERE
|
130
|
+
(
|
131
|
+
m.genre = 'Sci-Fi'
|
132
|
+
OR
|
133
|
+
m.awards LIKE '%Oscar%'
|
134
|
+
)
|
135
|
+
AND a.age <= 69 AND a.age >= 45
|
136
|
+
ORDER BY
|
137
|
+
m.release_date DESC
|
138
|
+
"""
|
139
|
+
```
|
140
|
+
|
141
|
+
`a, c, m = Select.parse(text)`
|
142
|
+
|
143
|
+
**6.1 --- print(a)**
|
144
|
+
```
|
145
|
+
SELECT
|
146
|
+
a.name as actors_name
|
147
|
+
FROM
|
148
|
+
Actor a
|
149
|
+
WHERE
|
150
|
+
a.age <= 69
|
151
|
+
AND a.age >= 45
|
152
|
+
```
|
153
|
+
|
154
|
+
**6.2 --- print(c)**
|
155
|
+
|
156
|
+
SELECT
|
157
|
+
c.role
|
158
|
+
FROM
|
159
|
+
Cast c
|
160
|
+
|
161
|
+
**6.3 --- print(m)**
|
162
|
+
|
163
|
+
SELECT
|
164
|
+
m.title,
|
165
|
+
m.release_date
|
166
|
+
FROM
|
167
|
+
Movie m
|
168
|
+
WHERE
|
169
|
+
( m.genre = 'Sci-Fi' OR m.awards LIKE '%Oscar%' )
|
170
|
+
ORDER BY
|
171
|
+
m.release_date DESC
|
172
|
+
|
173
|
+
|
174
|
+
|
175
|
+
**6.4 --- print(a+c)**
|
176
|
+
|
177
|
+
SELECT
|
178
|
+
a.name as actors_name,
|
179
|
+
cas.role
|
180
|
+
FROM
|
181
|
+
Actor a
|
182
|
+
JOIN Cast cas ON (a.cast = cas.id)
|
183
|
+
WHERE
|
184
|
+
a.age >= 45
|
185
|
+
AND a.age <= 69
|
186
|
+
|
187
|
+
**6.5 --- print(c+m)**
|
188
|
+
> `... or print(m+c)`
|
189
|
+
|
190
|
+
SELECT
|
191
|
+
cas.role,
|
192
|
+
m.title,
|
193
|
+
m.release_date,
|
194
|
+
m.director
|
195
|
+
FROM
|
196
|
+
Cast cas
|
197
|
+
JOIN Movie m ON (cas.movie = m.id)
|
198
|
+
WHERE
|
199
|
+
( m.genre = 'Sci-Fi' OR m.awards LIKE '%Oscar%' )
|
200
|
+
AND m.director LIKE '%Coppola%'
|
201
|
+
ORDER BY
|
202
|
+
m.release_date,
|
203
|
+
m.director
|
204
|
+
---
|
205
|
+
|
206
|
+
### 7 - You can add or delete attributes directly in objects:
|
207
|
+
* a(gender=Field)
|
208
|
+
* m.delete('director')
|
209
|
+
|
210
|
+
---
|
211
|
+
|
212
|
+
### 8 - Defining relationship on separate objects:
|
213
|
+
```
|
214
|
+
a = Select...
|
215
|
+
c = Select...
|
216
|
+
m = Select...
|
217
|
+
```
|
218
|
+
`a + c => ERROR: "No relationship found between Actor and Cast"`
|
219
|
+
|
220
|
+
8.1 - But...
|
221
|
+
|
222
|
+
a( cast=ForeignKey('Cast') )
|
223
|
+
c(id=PrimaryKey)
|
224
|
+
|
225
|
+
**a + c => Ok!**
|
226
|
+
|
227
|
+
8.2
|
228
|
+
|
229
|
+
c( movie=ForeignKey('Movie') )
|
230
|
+
m(id=PrimaryKey)
|
231
|
+
|
232
|
+
> **c + m => Ok!**
|
233
|
+
>> **m + c => Ok!**
|
234
|
+
|
235
|
+
|
236
|
+
---
|
237
|
+
|
238
|
+
### 9 - Comparing objects
|
239
|
+
|
240
|
+
9.1
|
241
|
+
```
|
242
|
+
a1 = Select.parse('''
|
243
|
+
SELECT gender, max(age) FROM Actor act
|
244
|
+
WHERE act.age <= 69 AND act.age >= 45
|
245
|
+
GROUP BY gender
|
246
|
+
''')[0]
|
247
|
+
|
248
|
+
a2 = Select('Actor',
|
249
|
+
age=Between(45, 69), gender=GroupBy,
|
250
|
+
gender=[GroupBy, Field]
|
251
|
+
)
|
252
|
+
```
|
253
|
+
> **a1 == a2 # --- True!**
|
254
|
+
|
255
|
+
|
256
|
+
|
257
|
+
9.2
|
258
|
+
```
|
259
|
+
m1 = Select.parse("""
|
260
|
+
SELECT title, release_date FROM Movie m ORDER BY release_date
|
261
|
+
WHERE m.genre = 'Sci-Fi' AND m.awards LIKE '%Oscar%'
|
262
|
+
""")[0]
|
263
|
+
|
264
|
+
m2 = Select.parse("""
|
265
|
+
SELECT release_date, title
|
266
|
+
FROM Movie m
|
267
|
+
WHERE m.awards LIKE '%Oscar%' AND m.genre = 'Sci-Fi'
|
268
|
+
ORDER BY release_date
|
269
|
+
""")[0]
|
270
|
+
```
|
271
|
+
|
272
|
+
**m1 == m2 # --- True!**
|
273
|
+
|
274
|
+
|
275
|
+
9.3
|
276
|
+
```
|
277
|
+
best_movies = SubSelect(
|
278
|
+
Review=Table('role'),
|
279
|
+
rate=[GroupBy, Having.avg(Where.gt(4.5))]
|
280
|
+
)
|
281
|
+
m1 = Select(
|
282
|
+
Movie=Table('title,release_date),
|
283
|
+
id=best_movies
|
284
|
+
)
|
285
|
+
|
286
|
+
sql = "SELECT rev.role FROM Review rev GROUP BY rev.rate HAVING Avg(rev.rate) > 4.5"
|
287
|
+
m2 = Select(
|
288
|
+
'Movie', release_date=Field, title=Field,
|
289
|
+
id=Where(f"IN ({sql})")
|
290
|
+
)
|
291
|
+
```
|
292
|
+
**m1 == m2 # --- True!**
|
293
|
+
|
294
|
+
---
|
295
|
+
---
|
296
|
+
|
@@ -0,0 +1,281 @@
|
|
1
|
+
# SQL_Blocks
|
2
|
+
|
3
|
+
### 1 - You can assemble a simple object that will then be converted into an SQL command:
|
4
|
+
|
5
|
+
> a = Select('Actor') # --> SELECT * FROM Actor act
|
6
|
+
|
7
|
+
_Note that an alias "act" has been added._
|
8
|
+
|
9
|
+
You can specify your own alias: `a = Select('Actor a')`
|
10
|
+
|
11
|
+
---
|
12
|
+
### 2 - You can also add a field, like this...
|
13
|
+
|
14
|
+
* a = Select('Actor a', **name=Field**)
|
15
|
+
|
16
|
+
* Here are another ways to add a field:
|
17
|
+
- Select('Actor a', name=Distinct )
|
18
|
+
|
19
|
+
- Select('Actor a', name=NamedField('actors_name'))
|
20
|
+
|
21
|
+
- Select(
|
22
|
+
'Actor a',
|
23
|
+
name=NamedField('actors_name'), Distinct
|
24
|
+
)
|
25
|
+
|
26
|
+
---
|
27
|
+
|
28
|
+
### 3 - To set conditions, use **Where**:
|
29
|
+
* For example, `a = Select(... age=Where.gt(45) )`
|
30
|
+
|
31
|
+
Some possible conditions:
|
32
|
+
* field=Where.eq(value) - ...the field is EQUAL to the value;
|
33
|
+
* field=Where.gt(value) - ...the field is GREATER than the value;
|
34
|
+
* field=Where.lt(value) - ...the field is LESS than the value;
|
35
|
+
|
36
|
+
3.1 -- If you want to filter the field on a range of values:
|
37
|
+
|
38
|
+
`a = Select( 'Actor a', age=Between(45, 69) )`
|
39
|
+
|
40
|
+
3.2 -- Sub-queries:
|
41
|
+
|
42
|
+
```
|
43
|
+
query = Select('Movie m', title=Field,
|
44
|
+
id=SubSelect(
|
45
|
+
'Review r',
|
46
|
+
rate=Where.gt(4.5),
|
47
|
+
movie_id=Distinct
|
48
|
+
)
|
49
|
+
)
|
50
|
+
```
|
51
|
+
|
52
|
+
**>> print(query)**
|
53
|
+
|
54
|
+
SELECT
|
55
|
+
m.title
|
56
|
+
FROM
|
57
|
+
Movie m
|
58
|
+
WHERE
|
59
|
+
m.id IN (
|
60
|
+
SELECT DISTINCT r.movie
|
61
|
+
FROM Review r WHERE r.rate > 4.5
|
62
|
+
)
|
63
|
+
|
64
|
+
3.3 -- Optional conditions:
|
65
|
+
```
|
66
|
+
OR=Options(
|
67
|
+
genre=Where.eq("Sci-Fi"),
|
68
|
+
awards=Where.like("Oscar")
|
69
|
+
)
|
70
|
+
```
|
71
|
+
> Could be AND=Options(...)
|
72
|
+
|
73
|
+
---
|
74
|
+
### 4 - A field can be two things at the same time:
|
75
|
+
|
76
|
+
* m = Select('Movie m' release_date=[Field, OrderBy])
|
77
|
+
- This means that the field will appear in the results and also that the query will be ordered by that field.
|
78
|
+
* Applying **GROUP BY** to item 3.2, it would look like this:
|
79
|
+
```
|
80
|
+
SubSelect(
|
81
|
+
'Review r', movie=[GroupBy, Distinct],
|
82
|
+
rate=Having.avg(Where.gt(4.5))
|
83
|
+
)
|
84
|
+
```
|
85
|
+
---
|
86
|
+
### 5 - Relationships:
|
87
|
+
```
|
88
|
+
query = Select('Actor a', name=Field,
|
89
|
+
cast=Select('Cast c', id=PrimaryKey)
|
90
|
+
)
|
91
|
+
```
|
92
|
+
**>> print(query)**
|
93
|
+
```
|
94
|
+
SELECT
|
95
|
+
a.name
|
96
|
+
FROM
|
97
|
+
Actor a
|
98
|
+
JOIN Cast c ON (a.cast = c.id)
|
99
|
+
```
|
100
|
+
|
101
|
+
---
|
102
|
+
### 6 - The reverse process (parse):
|
103
|
+
```
|
104
|
+
text = """
|
105
|
+
SELECT
|
106
|
+
cas.role,
|
107
|
+
m.title,
|
108
|
+
m.release_date,
|
109
|
+
a.name as actors_name
|
110
|
+
FROM
|
111
|
+
Actor a
|
112
|
+
LEFT JOIN Cast cas ON (a.cast = cas.id)
|
113
|
+
LEFT JOIN Movie m ON (cas.movie = m.id)
|
114
|
+
WHERE
|
115
|
+
(
|
116
|
+
m.genre = 'Sci-Fi'
|
117
|
+
OR
|
118
|
+
m.awards LIKE '%Oscar%'
|
119
|
+
)
|
120
|
+
AND a.age <= 69 AND a.age >= 45
|
121
|
+
ORDER BY
|
122
|
+
m.release_date DESC
|
123
|
+
"""
|
124
|
+
```
|
125
|
+
|
126
|
+
`a, c, m = Select.parse(text)`
|
127
|
+
|
128
|
+
**6.1 --- print(a)**
|
129
|
+
```
|
130
|
+
SELECT
|
131
|
+
a.name as actors_name
|
132
|
+
FROM
|
133
|
+
Actor a
|
134
|
+
WHERE
|
135
|
+
a.age <= 69
|
136
|
+
AND a.age >= 45
|
137
|
+
```
|
138
|
+
|
139
|
+
**6.2 --- print(c)**
|
140
|
+
|
141
|
+
SELECT
|
142
|
+
c.role
|
143
|
+
FROM
|
144
|
+
Cast c
|
145
|
+
|
146
|
+
**6.3 --- print(m)**
|
147
|
+
|
148
|
+
SELECT
|
149
|
+
m.title,
|
150
|
+
m.release_date
|
151
|
+
FROM
|
152
|
+
Movie m
|
153
|
+
WHERE
|
154
|
+
( m.genre = 'Sci-Fi' OR m.awards LIKE '%Oscar%' )
|
155
|
+
ORDER BY
|
156
|
+
m.release_date DESC
|
157
|
+
|
158
|
+
|
159
|
+
|
160
|
+
**6.4 --- print(a+c)**
|
161
|
+
|
162
|
+
SELECT
|
163
|
+
a.name as actors_name,
|
164
|
+
cas.role
|
165
|
+
FROM
|
166
|
+
Actor a
|
167
|
+
JOIN Cast cas ON (a.cast = cas.id)
|
168
|
+
WHERE
|
169
|
+
a.age >= 45
|
170
|
+
AND a.age <= 69
|
171
|
+
|
172
|
+
**6.5 --- print(c+m)**
|
173
|
+
> `... or print(m+c)`
|
174
|
+
|
175
|
+
SELECT
|
176
|
+
cas.role,
|
177
|
+
m.title,
|
178
|
+
m.release_date,
|
179
|
+
m.director
|
180
|
+
FROM
|
181
|
+
Cast cas
|
182
|
+
JOIN Movie m ON (cas.movie = m.id)
|
183
|
+
WHERE
|
184
|
+
( m.genre = 'Sci-Fi' OR m.awards LIKE '%Oscar%' )
|
185
|
+
AND m.director LIKE '%Coppola%'
|
186
|
+
ORDER BY
|
187
|
+
m.release_date,
|
188
|
+
m.director
|
189
|
+
---
|
190
|
+
|
191
|
+
### 7 - You can add or delete attributes directly in objects:
|
192
|
+
* a(gender=Field)
|
193
|
+
* m.delete('director')
|
194
|
+
|
195
|
+
---
|
196
|
+
|
197
|
+
### 8 - Defining relationship on separate objects:
|
198
|
+
```
|
199
|
+
a = Select...
|
200
|
+
c = Select...
|
201
|
+
m = Select...
|
202
|
+
```
|
203
|
+
`a + c => ERROR: "No relationship found between Actor and Cast"`
|
204
|
+
|
205
|
+
8.1 - But...
|
206
|
+
|
207
|
+
a( cast=ForeignKey('Cast') )
|
208
|
+
c(id=PrimaryKey)
|
209
|
+
|
210
|
+
**a + c => Ok!**
|
211
|
+
|
212
|
+
8.2
|
213
|
+
|
214
|
+
c( movie=ForeignKey('Movie') )
|
215
|
+
m(id=PrimaryKey)
|
216
|
+
|
217
|
+
> **c + m => Ok!**
|
218
|
+
>> **m + c => Ok!**
|
219
|
+
|
220
|
+
|
221
|
+
---
|
222
|
+
|
223
|
+
### 9 - Comparing objects
|
224
|
+
|
225
|
+
9.1
|
226
|
+
```
|
227
|
+
a1 = Select.parse('''
|
228
|
+
SELECT gender, max(age) FROM Actor act
|
229
|
+
WHERE act.age <= 69 AND act.age >= 45
|
230
|
+
GROUP BY gender
|
231
|
+
''')[0]
|
232
|
+
|
233
|
+
a2 = Select('Actor',
|
234
|
+
age=Between(45, 69), gender=GroupBy,
|
235
|
+
gender=[GroupBy, Field]
|
236
|
+
)
|
237
|
+
```
|
238
|
+
> **a1 == a2 # --- True!**
|
239
|
+
|
240
|
+
|
241
|
+
|
242
|
+
9.2
|
243
|
+
```
|
244
|
+
m1 = Select.parse("""
|
245
|
+
SELECT title, release_date FROM Movie m ORDER BY release_date
|
246
|
+
WHERE m.genre = 'Sci-Fi' AND m.awards LIKE '%Oscar%'
|
247
|
+
""")[0]
|
248
|
+
|
249
|
+
m2 = Select.parse("""
|
250
|
+
SELECT release_date, title
|
251
|
+
FROM Movie m
|
252
|
+
WHERE m.awards LIKE '%Oscar%' AND m.genre = 'Sci-Fi'
|
253
|
+
ORDER BY release_date
|
254
|
+
""")[0]
|
255
|
+
```
|
256
|
+
|
257
|
+
**m1 == m2 # --- True!**
|
258
|
+
|
259
|
+
|
260
|
+
9.3
|
261
|
+
```
|
262
|
+
best_movies = SubSelect(
|
263
|
+
Review=Table('role'),
|
264
|
+
rate=[GroupBy, Having.avg(Where.gt(4.5))]
|
265
|
+
)
|
266
|
+
m1 = Select(
|
267
|
+
Movie=Table('title,release_date),
|
268
|
+
id=best_movies
|
269
|
+
)
|
270
|
+
|
271
|
+
sql = "SELECT rev.role FROM Review rev GROUP BY rev.rate HAVING Avg(rev.rate) > 4.5"
|
272
|
+
m2 = Select(
|
273
|
+
'Movie', release_date=Field, title=Field,
|
274
|
+
id=Where(f"IN ({sql})")
|
275
|
+
)
|
276
|
+
```
|
277
|
+
**m1 == m2 # --- True!**
|
278
|
+
|
279
|
+
---
|
280
|
+
---
|
281
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
[project]
|
2
|
+
name = "sql_blocks"
|
3
|
+
version = "0.0.1"
|
4
|
+
authors = [
|
5
|
+
{ name="Julio Cascalles", email="julio.cascalles@outlook.com" },
|
6
|
+
]
|
7
|
+
description = '''Allows you to create objects for parts of SQL query commands. Also to combine these objects by joining them, adding or removing parts...'''
|
8
|
+
readme = "README.md"
|
9
|
+
requires-python = ">=3.8"
|
10
|
+
classifiers = [
|
11
|
+
"Programming Language :: Python :: 3",
|
12
|
+
"License :: OSI Approved :: MIT License",
|
13
|
+
"Operating System :: OS Independent",
|
14
|
+
]
|
15
|
+
|
16
|
+
[project.urls]
|
17
|
+
Homepage = "https://github.com/julio-cascalles/sql_blocks"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
from setuptools import setup
|
2
|
+
|
3
|
+
|
4
|
+
setup(
|
5
|
+
name = 'sql_blocks',
|
6
|
+
version = '1.0.0',
|
7
|
+
author = 'Júlio Cascalles',
|
8
|
+
author_email = 'julio.cascalles@outlook.com',
|
9
|
+
packages = ['sql_blocks'],
|
10
|
+
url = 'https://github.com/julio-cascalles/sql_blocks',
|
11
|
+
classifiers = [
|
12
|
+
'Development Status :: 5 - Production/Stable',
|
13
|
+
'Intended Audience :: Developers',
|
14
|
+
'License :: OSI Approved :: MIT License',
|
15
|
+
'Natural Language :: Portuguese (Brazilian)',
|
16
|
+
'Operating System :: OS Independent',
|
17
|
+
'Topic :: Software Development',
|
18
|
+
]
|
19
|
+
)
|
@@ -0,0 +1 @@
|
|
1
|
+
from sql_blocks import *
|