velocity-python 0.0.27__py3-none-any.whl → 0.0.29__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.
Potentially problematic release.
This version of velocity-python might be problematic. Click here for more details.
- velocity/__init__.py +1 -1
- velocity/db/core/decorators.py +60 -41
- velocity/db/core/row.py +33 -21
- velocity/db/core/table.py +318 -169
- velocity/db/core/transaction.py +54 -31
- velocity/db/servers/postgres.py +810 -689
- {velocity_python-0.0.27.dist-info → velocity_python-0.0.29.dist-info}/METADATA +1 -1
- {velocity_python-0.0.27.dist-info → velocity_python-0.0.29.dist-info}/RECORD +11 -12
- velocity/db/servers/sql.py +0 -558
- {velocity_python-0.0.27.dist-info → velocity_python-0.0.29.dist-info}/LICENSE +0 -0
- {velocity_python-0.0.27.dist-info → velocity_python-0.0.29.dist-info}/WHEEL +0 -0
- {velocity_python-0.0.27.dist-info → velocity_python-0.0.29.dist-info}/top_level.txt +0 -0
velocity/db/core/table.py
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
|
-
from velocity.db import exceptions
|
|
1
|
+
from velocity.db import exceptions
|
|
2
2
|
from velocity.db.core.row import Row
|
|
3
|
-
from velocity.db.servers.sql import Query
|
|
4
3
|
from velocity.db.core.result import Result
|
|
5
4
|
from velocity.db.core.column import Column
|
|
6
|
-
from velocity.db.core.decorators import
|
|
7
|
-
|
|
5
|
+
from velocity.db.core.decorators import (
|
|
6
|
+
return_default,
|
|
7
|
+
create_missing,
|
|
8
|
+
reset_id_on_dup_key,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Query(str):
|
|
13
|
+
pass
|
|
14
|
+
|
|
8
15
|
|
|
9
16
|
class Table(object):
|
|
10
17
|
def __init__(self, tx, name):
|
|
11
18
|
self.tx = tx
|
|
12
|
-
assert
|
|
19
|
+
assert self.tx
|
|
13
20
|
self.name = name.lower()
|
|
14
|
-
assert
|
|
21
|
+
assert self.name
|
|
15
22
|
self.sql = tx.engine.sql
|
|
16
|
-
assert
|
|
23
|
+
assert self.sql
|
|
17
24
|
|
|
18
25
|
def __str__(self):
|
|
19
26
|
return """
|
|
@@ -22,10 +29,10 @@ class Table(object):
|
|
|
22
29
|
Columns: %s
|
|
23
30
|
Rows: %s
|
|
24
31
|
""" % (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
self.name,
|
|
33
|
+
self.exists(),
|
|
34
|
+
len(self.columns),
|
|
35
|
+
len(self),
|
|
29
36
|
)
|
|
30
37
|
|
|
31
38
|
def __enter__(self):
|
|
@@ -50,13 +57,13 @@ class Table(object):
|
|
|
50
57
|
return self._cursor
|
|
51
58
|
|
|
52
59
|
def __call__(self, where=None):
|
|
53
|
-
sql,val = self.sql.select(table=self.name,where=where)
|
|
54
|
-
for data in self.tx.execute(sql,val):
|
|
60
|
+
sql, val = self.sql.select(table=self.name, where=where)
|
|
61
|
+
for data in self.tx.execute(sql, val):
|
|
55
62
|
yield self.row(data)
|
|
56
63
|
|
|
57
64
|
def __iter__(self):
|
|
58
|
-
sql,val = self.sql.select(table=self.name, orderby="sys_id")
|
|
59
|
-
for data in self.tx.execute(sql,val):
|
|
65
|
+
sql, val = self.sql.select(table=self.name, orderby="sys_id")
|
|
66
|
+
for data in self.tx.execute(sql, val):
|
|
60
67
|
yield self.row(data)
|
|
61
68
|
|
|
62
69
|
@property
|
|
@@ -69,13 +76,15 @@ class Table(object):
|
|
|
69
76
|
def columns(self):
|
|
70
77
|
columns = []
|
|
71
78
|
for column in self.sys_columns:
|
|
72
|
-
|
|
73
|
-
|
|
79
|
+
if "sys_" not in column:
|
|
80
|
+
columns.append(column)
|
|
74
81
|
return columns
|
|
75
82
|
|
|
76
|
-
@return_default(None)
|
|
83
|
+
@return_default(None, (exceptions.DbObjectExistsError,))
|
|
77
84
|
def create_index(self, columns, unique=False, direction=None, where=None, **kwds):
|
|
78
|
-
sql, vals = self.sql.create_index(
|
|
85
|
+
sql, vals = self.sql.create_index(
|
|
86
|
+
self.name, columns, unique, direction, where, tbl=self, **kwds
|
|
87
|
+
)
|
|
79
88
|
self.tx.execute(sql, vals, cursor=self.cursor)
|
|
80
89
|
|
|
81
90
|
@return_default(None)
|
|
@@ -99,7 +108,7 @@ class Table(object):
|
|
|
99
108
|
def exists(self):
|
|
100
109
|
sql, vals = self.sql.tables()
|
|
101
110
|
result = self.tx.execute(sql, vals, cursor=self.cursor)
|
|
102
|
-
if
|
|
111
|
+
if "." in self.name:
|
|
103
112
|
return bool(self.name in ["%s.%s" % x for x in result.as_tuple()])
|
|
104
113
|
else:
|
|
105
114
|
return bool(self.name in ["%s" % x[1] for x in result.as_tuple()])
|
|
@@ -107,95 +116,143 @@ class Table(object):
|
|
|
107
116
|
def column(self, name):
|
|
108
117
|
return Column(self, name)
|
|
109
118
|
|
|
110
|
-
def row(self, key=None):
|
|
119
|
+
def row(self, key=None, lock=None):
|
|
111
120
|
if key == None:
|
|
112
|
-
return self.new()
|
|
121
|
+
return self.new(lock=lock)
|
|
113
122
|
return Row(self, key)
|
|
114
123
|
|
|
115
124
|
def dict(self, key):
|
|
116
125
|
row = self.find(key)
|
|
117
126
|
return row.to_dict() if row else {}
|
|
118
127
|
|
|
119
|
-
def rows(self, where=None, orderby=None, qty=None):
|
|
120
|
-
for key in self.ids(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
128
|
+
def rows(self, where=None, orderby=None, qty=None, lock=None, skip_locked=None):
|
|
129
|
+
for key in self.ids(
|
|
130
|
+
where=where, orderby=orderby, qty=qty, lock=lock, skip_locked=skip_locked
|
|
131
|
+
):
|
|
132
|
+
yield Row(self, key, lock=lock)
|
|
133
|
+
|
|
134
|
+
def ids(
|
|
135
|
+
self,
|
|
136
|
+
where=None,
|
|
137
|
+
orderby=None,
|
|
138
|
+
groupby=None,
|
|
139
|
+
having=None,
|
|
140
|
+
start=None,
|
|
141
|
+
qty=None,
|
|
142
|
+
lock=None,
|
|
143
|
+
skip_locked=None,
|
|
144
|
+
):
|
|
145
|
+
for key in self.select(
|
|
146
|
+
"sys_id",
|
|
147
|
+
where=where,
|
|
148
|
+
orderby=orderby,
|
|
149
|
+
groupby=groupby,
|
|
150
|
+
having=having,
|
|
151
|
+
start=start,
|
|
152
|
+
qty=qty,
|
|
153
|
+
lock=lock,
|
|
154
|
+
skip_locked=skip_locked,
|
|
155
|
+
):
|
|
156
|
+
yield key["sys_id"]
|
|
126
157
|
|
|
127
158
|
def set_id(self, start):
|
|
128
159
|
sql, vals = self.sql.set_id(self.name, start)
|
|
129
160
|
result = self.tx.execute(sql, vals, cursor=self.cursor)
|
|
130
161
|
|
|
131
|
-
def new(self, data={
|
|
132
|
-
if len(data) == 1 and
|
|
133
|
-
return self.row(data).touch()
|
|
162
|
+
def new(self, data={"sys_modified": "@@CURRENT_TIMESTAMP"}, lock=None):
|
|
163
|
+
if len(data) == 1 and "sys_id" in data:
|
|
164
|
+
return self.row(data, lock=lock).touch()
|
|
134
165
|
val = self.insert(data)
|
|
135
166
|
sql, vals = self.sql.last_id(self.name)
|
|
136
167
|
sys_id = self.tx.execute(sql, vals).scalar()
|
|
137
|
-
return self.row(sys_id)
|
|
168
|
+
return self.row(sys_id, lock=lock)
|
|
138
169
|
|
|
139
|
-
def get(self, where):
|
|
170
|
+
def get(self, where, lock=None, use_where=False):
|
|
140
171
|
if where is None:
|
|
141
172
|
raise Exception("None is not allowed as a primary key")
|
|
142
173
|
if isinstance(where, int):
|
|
143
|
-
where = {
|
|
144
|
-
result = self.select(
|
|
174
|
+
where = {"sys_id": where}
|
|
175
|
+
result = self.select("sys_id", where=where, lock=lock).all()
|
|
145
176
|
if len(result) > 1:
|
|
146
|
-
sql = self.selectSQL(
|
|
147
|
-
raise exceptions.DuplicateRowsFoundError(
|
|
177
|
+
sql = self.selectSQL("sys_id", where=where, lock=lock)
|
|
178
|
+
raise exceptions.DuplicateRowsFoundError(
|
|
179
|
+
"More than one entry found. {}".format(sql)
|
|
180
|
+
)
|
|
148
181
|
elif len(result) < 1:
|
|
149
182
|
where = where.copy()
|
|
150
183
|
keys = list(where.keys())
|
|
151
184
|
for key in keys:
|
|
152
|
-
chars = set(
|
|
185
|
+
chars = set("<>!=%")
|
|
153
186
|
if any((c in chars) for c in key):
|
|
154
187
|
where.pop(key)
|
|
155
|
-
return self.new(where)
|
|
156
|
-
|
|
188
|
+
return self.new(where, lock=lock)
|
|
189
|
+
if use_where:
|
|
190
|
+
return Row(self, where, lock=lock)
|
|
191
|
+
else:
|
|
192
|
+
return Row(self, result[0]["sys_id"], lock=lock)
|
|
157
193
|
|
|
158
194
|
@return_default(None)
|
|
159
|
-
def find(self, where):
|
|
195
|
+
def find(self, where, lock=None, use_where=False):
|
|
160
196
|
if where is None:
|
|
161
197
|
raise Exception("None is not allowed as a primary key")
|
|
162
198
|
if isinstance(where, int):
|
|
163
|
-
where = {
|
|
164
|
-
result = self.select(
|
|
199
|
+
where = {"sys_id": where}
|
|
200
|
+
result = self.select("sys_id", where=where, lock=lock).all()
|
|
165
201
|
if len(result) > 1:
|
|
166
|
-
sql = self.selectSQL(
|
|
167
|
-
raise exceptions.DuplicateRowsFoundError(
|
|
202
|
+
sql = self.selectSQL("sys_id", where=where, lock=lock)
|
|
203
|
+
raise exceptions.DuplicateRowsFoundError(
|
|
204
|
+
"More than one entry found. {}".format(sql)
|
|
205
|
+
)
|
|
168
206
|
elif len(result) < 1:
|
|
169
207
|
return None
|
|
170
|
-
|
|
208
|
+
if use_where:
|
|
209
|
+
return Row(self, where, lock=lock)
|
|
210
|
+
else:
|
|
211
|
+
return Row(self, result[0]["sys_id"], lock=lock)
|
|
171
212
|
|
|
172
213
|
@return_default(None)
|
|
173
|
-
def first(
|
|
214
|
+
def first(
|
|
215
|
+
self,
|
|
216
|
+
where,
|
|
217
|
+
orderby=None,
|
|
218
|
+
create_new=False,
|
|
219
|
+
lock=None,
|
|
220
|
+
skip_locked=None,
|
|
221
|
+
use_where=False,
|
|
222
|
+
):
|
|
174
223
|
if where is None:
|
|
175
|
-
raise Exception("None is not allowed as a
|
|
224
|
+
raise Exception("None is not allowed as a where clause")
|
|
176
225
|
if isinstance(where, int):
|
|
177
|
-
where = {
|
|
178
|
-
result = self.select(
|
|
226
|
+
where = {"sys_id": where}
|
|
227
|
+
result = self.select(
|
|
228
|
+
"sys_id", where=where, orderby=orderby, skip_locked=skip_locked
|
|
229
|
+
).all()
|
|
179
230
|
if len(result) < 1:
|
|
180
231
|
if create_new:
|
|
181
232
|
where = where.copy()
|
|
182
233
|
keys = list(where.keys())
|
|
183
234
|
for key in keys:
|
|
184
|
-
chars = set(
|
|
235
|
+
chars = set("<>!=%")
|
|
185
236
|
if any((c in chars) for c in key):
|
|
186
237
|
where.pop(key)
|
|
187
|
-
return self.new(where)
|
|
238
|
+
return self.new(where, lock=lock)
|
|
188
239
|
return None
|
|
189
|
-
|
|
240
|
+
if use_where:
|
|
241
|
+
return Row(self, where, lock=lock)
|
|
242
|
+
else:
|
|
243
|
+
return Row(self, result[0]["sys_id"], lock=lock)
|
|
190
244
|
|
|
191
245
|
@return_default(None)
|
|
192
|
-
def one(self, where=None, orderby=None):
|
|
246
|
+
def one(self, where=None, orderby=None, lock=None, use_where=False):
|
|
193
247
|
if isinstance(where, int):
|
|
194
|
-
where = {
|
|
195
|
-
result = self.select(
|
|
248
|
+
where = {"sys_id": where}
|
|
249
|
+
result = self.select("sys_id", where=where, orderby=orderby).all()
|
|
196
250
|
if len(result) < 1:
|
|
197
251
|
return None
|
|
198
|
-
|
|
252
|
+
if use_where:
|
|
253
|
+
return Row(self, where, lock=lock)
|
|
254
|
+
else:
|
|
255
|
+
return Row(self, result[0]["sys_id"], lock=lock)
|
|
199
256
|
|
|
200
257
|
@property
|
|
201
258
|
def primary_keys(self):
|
|
@@ -214,12 +271,16 @@ class Table(object):
|
|
|
214
271
|
return self.tx.execute(sql, vals, cursor=self.cursor).one()
|
|
215
272
|
|
|
216
273
|
@return_default()
|
|
217
|
-
def create_foreign_key(self, columns, key_to_table, key_to_columns=
|
|
218
|
-
sql, vals = self.sql.create_foreign_key(
|
|
274
|
+
def create_foreign_key(self, columns, key_to_table, key_to_columns="sys_id"):
|
|
275
|
+
sql, vals = self.sql.create_foreign_key(
|
|
276
|
+
self.name, columns, key_to_table, key_to_columns
|
|
277
|
+
)
|
|
219
278
|
return self.tx.execute(sql, vals, cursor=self.cursor)
|
|
220
279
|
|
|
221
|
-
def drop_foreign_key(self, columns, key_to_table, key_to_columns=
|
|
222
|
-
sql, vals = self.sql.create_foreign_key(
|
|
280
|
+
def drop_foreign_key(self, columns, key_to_table, key_to_columns="sys_id"):
|
|
281
|
+
sql, vals = self.sql.create_foreign_key(
|
|
282
|
+
self.name, columns, key_to_table, key_to_columns
|
|
283
|
+
)
|
|
223
284
|
return self.tx.execute(sql, vals, cursor=self.cursor)
|
|
224
285
|
|
|
225
286
|
def rename(self, name):
|
|
@@ -229,7 +290,7 @@ class Table(object):
|
|
|
229
290
|
|
|
230
291
|
def lower_keys(self, arg):
|
|
231
292
|
new = {}
|
|
232
|
-
if isinstance(arg,dict):
|
|
293
|
+
if isinstance(arg, dict):
|
|
233
294
|
for key in list(arg.keys()):
|
|
234
295
|
new[key.lower()] = arg[key]
|
|
235
296
|
return new
|
|
@@ -241,146 +302,226 @@ class Table(object):
|
|
|
241
302
|
columns = self.lower_keys(columns)
|
|
242
303
|
# Need to maintain order of keys
|
|
243
304
|
for k in list(columns.keys()):
|
|
244
|
-
diff.append(k) if k not in self.
|
|
305
|
+
diff.append(k) if k not in self.sys_columns else None
|
|
245
306
|
else:
|
|
246
|
-
raise Exception(
|
|
307
|
+
raise Exception(
|
|
308
|
+
"I don't know how to handle columns data type in this context"
|
|
309
|
+
)
|
|
247
310
|
if diff:
|
|
248
|
-
new = dict([(key,columns[key]) for key in diff
|
|
311
|
+
new = dict([(key, columns[key]) for key in diff])
|
|
249
312
|
sql, vals = self.sql.alter_add(self.name, new)
|
|
250
313
|
self.tx.execute(sql, vals, cursor=self.cursor)
|
|
251
314
|
|
|
252
315
|
@create_missing
|
|
253
316
|
def alter_type(self, column, type_or_value, nullable=True):
|
|
254
|
-
sql, vals = self.sql.alter_column_by_type(
|
|
317
|
+
sql, vals = self.sql.alter_column_by_type(
|
|
318
|
+
self.name, column, type_or_value, nullable
|
|
319
|
+
)
|
|
255
320
|
self.tx.execute(sql, vals, cursor=self.cursor)
|
|
256
321
|
|
|
257
322
|
@create_missing
|
|
258
|
-
def update(self, data, pk, left_join=None, inner_join
|
|
259
|
-
sql, vals = self.sql.update(
|
|
323
|
+
def update(self, data, pk, left_join=None, inner_join=None, outer_join=None):
|
|
324
|
+
sql, vals = self.sql.update(
|
|
325
|
+
self.name, data, pk, left_join, inner_join, outer_join
|
|
326
|
+
)
|
|
260
327
|
result = self.tx.execute(sql, vals, cursor=self.cursor)
|
|
261
328
|
return result.cursor.rowcount
|
|
262
329
|
|
|
263
|
-
@
|
|
330
|
+
@reset_id_on_dup_key
|
|
264
331
|
@create_missing
|
|
265
332
|
def insert(self, data):
|
|
266
333
|
sql, vals = self.sql.insert(self.name, data)
|
|
267
334
|
result = self.tx.execute(sql, vals, cursor=self.cursor)
|
|
268
335
|
return result.cursor.rowcount
|
|
269
336
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
337
|
+
@reset_id_on_dup_key
|
|
338
|
+
@create_missing
|
|
339
|
+
def merge(self, data, pk):
|
|
340
|
+
sql, vals = self.sql.merge(
|
|
341
|
+
self.name, data, pk, on_conflict_do_nothing=False, on_conflict_update=True
|
|
342
|
+
)
|
|
343
|
+
result = self.tx.execute(sql, vals, cursor=self.cursor)
|
|
344
|
+
return result.cursor.rowcount
|
|
276
345
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
except exceptions.DbDuplicateKeyError:
|
|
285
|
-
self.tx.rollback_savepoint(sp, cursor=self.cursor)
|
|
286
|
-
self.update(data, pk)
|
|
346
|
+
upsert = merge
|
|
347
|
+
indate = merge
|
|
348
|
+
|
|
349
|
+
def mergeSQL(self, data, pk):
|
|
350
|
+
return self.sql.merge(
|
|
351
|
+
self.name, data, pk, on_conflict_do_nothing=False, on_conflict_update=True
|
|
352
|
+
)
|
|
287
353
|
|
|
288
|
-
def
|
|
354
|
+
def insertSQL(self, data):
|
|
355
|
+
return self.sql.insert(self.name, data)
|
|
356
|
+
|
|
357
|
+
def updateSQL(self, data, pk, left_join=None, inner_join=None, outer_join=None):
|
|
289
358
|
return self.sql.update(self.name, data, pk, left_join, inner_join, outer_join)
|
|
290
359
|
|
|
291
360
|
@return_default(0)
|
|
292
361
|
def count(self, where=None):
|
|
293
|
-
sql, vals = self.sql.select(columns=
|
|
362
|
+
sql, vals = self.sql.select(columns="count(*)", table=self.name, where=where)
|
|
294
363
|
return self.tx.execute(sql, vals, cursor=self.cursor).scalar()
|
|
295
364
|
|
|
296
365
|
@return_default(0)
|
|
297
366
|
def sum(self, column, where=None):
|
|
298
|
-
sql, vals = self.sql.select(
|
|
367
|
+
sql, vals = self.sql.select(
|
|
368
|
+
columns="coalesce(sum(coalesce({},0)),0)".format(column),
|
|
369
|
+
table=self.name,
|
|
370
|
+
where=where,
|
|
371
|
+
)
|
|
299
372
|
return self.tx.execute(sql, vals, cursor=self.cursor).scalar()
|
|
300
373
|
|
|
301
374
|
@return_default(0)
|
|
302
375
|
def __len__(self):
|
|
303
|
-
sql, vals = self.sql.select(columns=
|
|
376
|
+
sql, vals = self.sql.select(columns="count(*)", table=self.name)
|
|
304
377
|
return self.tx.execute(sql, vals, cursor=self.cursor).scalar()
|
|
305
378
|
|
|
306
379
|
@return_default(None)
|
|
307
|
-
def oldest(self, where={}, field=
|
|
308
|
-
sql,vals = self.sql.select(
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
380
|
+
def oldest(self, where={}, field="sys_modified", columns="sys_id", lock=None):
|
|
381
|
+
sql, vals = self.sql.select(
|
|
382
|
+
columns=columns,
|
|
383
|
+
table=self.name,
|
|
384
|
+
where=where,
|
|
385
|
+
orderby=field + " asc",
|
|
386
|
+
qty=1,
|
|
387
|
+
lock=lock,
|
|
388
|
+
)
|
|
313
389
|
return self.tx.execute(sql, vals, cursor=self.cursor).scalar()
|
|
314
390
|
|
|
315
391
|
@return_default(None)
|
|
316
|
-
def newest(self, where={}, field=
|
|
317
|
-
sql,vals = self.sql.select(
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
392
|
+
def newest(self, where={}, field="sys_modified", columns="sys_id", lock=None):
|
|
393
|
+
sql, vals = self.sql.select(
|
|
394
|
+
columns=columns,
|
|
395
|
+
table=self.name,
|
|
396
|
+
where=where,
|
|
397
|
+
orderby=field + " desc",
|
|
398
|
+
qty=1,
|
|
399
|
+
lock=lock,
|
|
400
|
+
)
|
|
322
401
|
return self.tx.execute(sql, vals, cursor=self.cursor).scalar()
|
|
323
402
|
|
|
324
403
|
@return_default(Result())
|
|
325
|
-
def select(
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
404
|
+
def select(
|
|
405
|
+
self,
|
|
406
|
+
columns=None,
|
|
407
|
+
where=None,
|
|
408
|
+
orderby=None,
|
|
409
|
+
groupby=None,
|
|
410
|
+
having=None,
|
|
411
|
+
start=None,
|
|
412
|
+
qty=None,
|
|
413
|
+
lock=None,
|
|
414
|
+
skip_locked=None,
|
|
415
|
+
):
|
|
416
|
+
sql, vals = self.sql.select(
|
|
417
|
+
columns=columns,
|
|
418
|
+
table=self.name,
|
|
419
|
+
where=where,
|
|
420
|
+
orderby=orderby,
|
|
421
|
+
groupby=groupby,
|
|
422
|
+
having=having,
|
|
423
|
+
start=start,
|
|
424
|
+
qty=qty,
|
|
425
|
+
tbl=self,
|
|
426
|
+
lock=lock,
|
|
427
|
+
skip_locked=skip_locked,
|
|
428
|
+
)
|
|
335
429
|
return self.tx.execute(sql, vals)
|
|
336
430
|
|
|
337
431
|
def list(self, *args, **kwds):
|
|
338
432
|
return self.select(*args, **kwds).all()
|
|
339
433
|
|
|
340
|
-
def selectSQL(
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
434
|
+
def selectSQL(
|
|
435
|
+
self,
|
|
436
|
+
columns=None,
|
|
437
|
+
where=None,
|
|
438
|
+
orderby=None,
|
|
439
|
+
groupby=None,
|
|
440
|
+
having=None,
|
|
441
|
+
start=None,
|
|
442
|
+
qty=None,
|
|
443
|
+
lock=None,
|
|
444
|
+
skip_locked=None,
|
|
445
|
+
):
|
|
446
|
+
return self.sql.select(
|
|
447
|
+
columns=columns,
|
|
448
|
+
table=self.name,
|
|
449
|
+
where=where,
|
|
450
|
+
orderby=orderby,
|
|
451
|
+
groupby=groupby,
|
|
452
|
+
having=having,
|
|
453
|
+
start=start,
|
|
454
|
+
qty=qty,
|
|
455
|
+
tbl=self,
|
|
456
|
+
lock=lock,
|
|
457
|
+
skip_locked=skip_locked,
|
|
458
|
+
)
|
|
459
|
+
|
|
460
|
+
def query(
|
|
461
|
+
self,
|
|
462
|
+
columns=None,
|
|
463
|
+
where=None,
|
|
464
|
+
orderby=None,
|
|
465
|
+
groupby=None,
|
|
466
|
+
having=None,
|
|
467
|
+
start=None,
|
|
468
|
+
qty=None,
|
|
469
|
+
lock=None,
|
|
470
|
+
skip_locked=None,
|
|
471
|
+
):
|
|
472
|
+
sql, vals = self.sql.select(
|
|
473
|
+
columns=columns,
|
|
474
|
+
table=self.name,
|
|
475
|
+
where=where,
|
|
476
|
+
orderby=orderby,
|
|
477
|
+
groupby=groupby,
|
|
478
|
+
having=having,
|
|
479
|
+
start=start,
|
|
480
|
+
qty=qty,
|
|
481
|
+
tbl=self,
|
|
482
|
+
lock=lock,
|
|
483
|
+
skip_locked=skip_locked,
|
|
484
|
+
)
|
|
361
485
|
if vals:
|
|
362
|
-
raise Exception(
|
|
486
|
+
raise Exception(
|
|
487
|
+
"a query generator does not support dictionary type as where clause"
|
|
488
|
+
)
|
|
363
489
|
return Query(sql)
|
|
364
490
|
|
|
365
491
|
@return_default(Result())
|
|
366
|
-
def server_select(
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
492
|
+
def server_select(
|
|
493
|
+
self,
|
|
494
|
+
columns=None,
|
|
495
|
+
where=None,
|
|
496
|
+
orderby=None,
|
|
497
|
+
groupby=None,
|
|
498
|
+
having=None,
|
|
499
|
+
start=None,
|
|
500
|
+
qty=None,
|
|
501
|
+
lock=None,
|
|
502
|
+
skip_locked=None,
|
|
503
|
+
):
|
|
504
|
+
sql, vals = self.sql.select(
|
|
505
|
+
columns=columns,
|
|
506
|
+
table=self.name,
|
|
507
|
+
where=where,
|
|
508
|
+
orderby=orderby,
|
|
509
|
+
groupby=groupby,
|
|
510
|
+
having=having,
|
|
511
|
+
start=start,
|
|
512
|
+
qty=qty,
|
|
513
|
+
tbl=self,
|
|
514
|
+
lock=lock,
|
|
515
|
+
skip_locked=skip_locked,
|
|
516
|
+
)
|
|
376
517
|
return self.tx.server_execute(sql, vals)
|
|
377
518
|
|
|
378
519
|
@return_default(Result())
|
|
379
520
|
def batch(self, size=100, *args, **kwds):
|
|
380
521
|
current = 0
|
|
381
522
|
while True:
|
|
382
|
-
kwds[
|
|
383
|
-
kwds[
|
|
523
|
+
kwds["start"] = current
|
|
524
|
+
kwds["qty"] = size
|
|
384
525
|
results = self.select(*args, **kwds).all()
|
|
385
526
|
if results:
|
|
386
527
|
yield results
|
|
@@ -388,21 +529,23 @@ class Table(object):
|
|
|
388
529
|
else:
|
|
389
530
|
raise StopIteration
|
|
390
531
|
|
|
391
|
-
|
|
392
|
-
|
|
393
532
|
def get_value(self, key, pk):
|
|
394
533
|
return self.select(columns=key, where=pk).scalar()
|
|
395
534
|
|
|
396
535
|
@return_default({})
|
|
397
|
-
def get_row(self, where):
|
|
536
|
+
def get_row(self, where, lock=None):
|
|
398
537
|
if not where:
|
|
399
538
|
raise Exception("Unique key for the row to be retrieved is required.")
|
|
400
|
-
sql, vals = self.sql.select(
|
|
539
|
+
sql, vals = self.sql.select(
|
|
540
|
+
columns="*", table=self.name, where=where, lock=lock
|
|
541
|
+
)
|
|
401
542
|
return self.tx.execute(sql, vals, cursor=self.cursor).one()
|
|
402
543
|
|
|
403
544
|
def delete(self, where):
|
|
404
545
|
if not where:
|
|
405
|
-
raise Exception(
|
|
546
|
+
raise Exception(
|
|
547
|
+
"You just tried to delete an entire table. Use truncate instead."
|
|
548
|
+
)
|
|
406
549
|
sql, vals = self.sql.delete(table=self.name, where=where)
|
|
407
550
|
result = self.tx.execute(sql, vals)
|
|
408
551
|
return result.cursor.rowcount
|
|
@@ -411,27 +554,31 @@ class Table(object):
|
|
|
411
554
|
sql, vals = self.sql.truncate(table=self.name)
|
|
412
555
|
self.tx.execute(sql, vals)
|
|
413
556
|
|
|
414
|
-
def
|
|
415
|
-
sql, vals = self.sql.
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
557
|
+
def duplicate_rows(self, columns=["sys_id"], where={}, group=False):
|
|
558
|
+
sql, vals = self.sql.duplicate_rows(self.name, columns, where)
|
|
559
|
+
for result in self.tx.execute(sql, vals):
|
|
560
|
+
result.update(where)
|
|
561
|
+
if group:
|
|
562
|
+
yield self.tx.table(self.name).select(where=result).all()
|
|
563
|
+
else:
|
|
564
|
+
for row in self.tx.table(self.name).select(where=result):
|
|
565
|
+
yield row
|
|
421
566
|
|
|
422
|
-
def
|
|
423
|
-
sql, vals = self.sql.
|
|
424
|
-
self.tx.execute(sql, vals)
|
|
567
|
+
def has_duplicates(self, columns=["sys_id"]):
|
|
568
|
+
sql, vals = self.sql.duplicate_rows(self.name, columns)
|
|
569
|
+
return bool([x for x in self.tx.execute(sql, vals)])
|
|
425
570
|
|
|
426
571
|
def create_view(self, name, query, temp=False, silent=True):
|
|
427
|
-
sql, vals = self.sql.create_view(
|
|
572
|
+
sql, vals = self.sql.create_view(
|
|
573
|
+
name=name, query=query, temp=temp, silent=silent
|
|
574
|
+
)
|
|
428
575
|
return self.tx.execute(sql, vals)
|
|
429
576
|
|
|
430
577
|
def drop_view(self, name, silent=True):
|
|
431
|
-
sql, vals = self.sql.drop_view(name=name,silent=silent)
|
|
578
|
+
sql, vals = self.sql.drop_view(name=name, silent=silent)
|
|
432
579
|
return self.tx.execute(sql, vals)
|
|
433
580
|
|
|
434
|
-
def alter_trigger(self, name=
|
|
581
|
+
def alter_trigger(self, name="USER", state="ENABLE"):
|
|
435
582
|
sql, vals = self.sql.alter_trigger(table=self.name, state=state, name=name)
|
|
436
583
|
return self.tx.execute(sql, vals)
|
|
437
584
|
|
|
@@ -442,13 +589,15 @@ class Table(object):
|
|
|
442
589
|
def set_sequence(self, next_value=1000):
|
|
443
590
|
sql, vals = self.sql.set_sequence(table=self.name, next_value=next_value)
|
|
444
591
|
return self.tx.execute(sql, vals).scalar()
|
|
445
|
-
|
|
592
|
+
|
|
446
593
|
def get_sequence(self):
|
|
447
594
|
sql, vals = self.sql.current_id(table=self.name)
|
|
448
595
|
return self.tx.execute(sql, vals).scalar()
|
|
449
|
-
|
|
450
|
-
def missing(self, list, column=
|
|
451
|
-
sql, vals = self.sql.missing(
|
|
596
|
+
|
|
597
|
+
def missing(self, list, column="sys_id", where=None):
|
|
598
|
+
sql, vals = self.sql.missing(
|
|
599
|
+
table=self.name, list=list, column=column, where=where
|
|
600
|
+
)
|
|
452
601
|
return self.tx.execute(sql, vals).as_simple_list().all()
|
|
453
602
|
|
|
454
603
|
def lock(self, mode="ACCESS EXCLUSIVE", wait_for_lock=None):
|
|
@@ -470,4 +619,4 @@ class Table(object):
|
|
|
470
619
|
sql, vals = self.sql.select(
|
|
471
620
|
columns="min({})".format(column), table=self.name, where=where
|
|
472
621
|
)
|
|
473
|
-
return self.tx.execute(sql, vals, cursor=self.cursor).scalar()
|
|
622
|
+
return self.tx.execute(sql, vals, cursor=self.cursor).scalar()
|