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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: velocity-python
3
- Version: 0.0.27
3
+ Version: 0.0.29
4
4
  Summary: A rapid application development library for interfacing with data storage
5
5
  Author-email: Paul Perez <pperez@codeclubs.org>
6
6
  Project-URL: Homepage, https://codeclubs.org/projects/velocity
@@ -1,4 +1,4 @@
1
- velocity/__init__.py,sha256=kg6GPjk7r3LPJXo60zCa5CAoMwhDkOEeMmdMTU38rUo,88
1
+ velocity/__init__.py,sha256=iVTlJ417T2VFb7sCoHxNQyxcJyZcz24nEWWJO8V_STU,88
2
2
  velocity/aws/__init__.py,sha256=ukvGrS0R8p6HtYajexOAJ7Kn9CJNlx6yb58W7o-JrAg,620
3
3
  velocity/aws/handlers/__init__.py,sha256=xnpFZJVlC2uoeeFW4zuPST8wA8ajaQDky5Y6iXZzi3A,172
4
4
  velocity/aws/handlers/context.py,sha256=UIjNR83y2NSIyK8HMPX8t5tpJHFNabiZvNgmmdQL3HA,1822
@@ -9,18 +9,17 @@ velocity/db/__init__.py,sha256=vrn2AFNAKaqTdnPwLFS0OcREcCtzUCOodlmH54U7ADg,200
9
9
  velocity/db/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  velocity/db/core/column.py,sha256=vB7dCrcIWFvRG1fgyzDQnEu7j_0KYxUuDSTCWVCYlPc,6153
11
11
  velocity/db/core/database.py,sha256=i1hzCkte6onEInH8ZtTI7D2Xj8q3uwU-uL3wn7Ix5oU,1860
12
- velocity/db/core/decorators.py,sha256=Y-ottCY3rJC2qWpDHQufU5khX-WkDba7_GfX2lon3Ss,2978
12
+ velocity/db/core/decorators.py,sha256=q3_0j06vZF9J-pPcLjsR2wftp4iXjlGgJ2l70WdtbUo,3271
13
13
  velocity/db/core/engine.py,sha256=94wVlnapVVmJCRp6NPGrwnqSxCDlC-848Vu42p9RtCs,14643
14
14
  velocity/db/core/exceptions.py,sha256=3ZyRq-idtCdtOGyT4rbNsmEyjfP75BMBq9y-Phakxow,684
15
15
  velocity/db/core/result.py,sha256=keE-SKn4Uw08uoiA_8FdaMzBfiaAIxidQEEsl3TM86U,4945
16
- velocity/db/core/row.py,sha256=QoTZtuO8K0VBZztIcdINmGiy0V4MLr_Z6FTzpJwHddU,5599
16
+ velocity/db/core/row.py,sha256=AHopXrrQUp5dCXEMLEDm0iAhswKDtMUdBxjTtPQ7Udk,5659
17
17
  velocity/db/core/sequence.py,sha256=6sUaHJ29ItthNYoAvQy0SMAZURRdDS8bomnmQspJaT4,1083
18
- velocity/db/core/table.py,sha256=VnwuuWHbQasa7TwDaB5fW7Qh0ia0NlA-WNpOZvKw_68,18030
19
- velocity/db/core/transaction.py,sha256=dZmYUvggPAkNBTM_nOgO-geUdJRNEMJENcDWhLqByJ0,6102
18
+ velocity/db/core/table.py,sha256=d7KyIXAinBBzIqvxIZClJ8d-DGskPucruFiFFT4PtCM,19805
19
+ velocity/db/core/transaction.py,sha256=XeqGkgrleIqC8krrDcqVXWiBAjXx9z67ZecJNjELgiw,6641
20
20
  velocity/db/servers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
21
  velocity/db/servers/mysql.py,sha256=c0yUG00jvgnhLMJcV8BuOlTL7uGJ3uRPjJ0xVJingbk,21975
22
- velocity/db/servers/postgres.py,sha256=H8WUrho-JC1X9M7zuUrEtOB3C5Yr9GnWCjPWrE9QDxQ,39672
23
- velocity/db/servers/sql.py,sha256=8yxljVYjMMY4weLCrugpLb7R3FEriHqamR-8lFaNfZg,21856
22
+ velocity/db/servers/postgres.py,sha256=aA4Fkz-PTo-Vi9kpDvWWMt2snv4r93PtQYDzgCg1XIs,42723
24
23
  velocity/db/servers/sqlite.py,sha256=QVdr_ytvCuSSKVgcP_PI05yTU0gNyFRtTmH4XQlQVjQ,34047
25
24
  velocity/db/servers/sqlserver.py,sha256=5kRNLNKbaszMww8JrlUvs2viSIb2hDZfn6nSvR52MEU,31593
26
25
  velocity/misc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -33,8 +32,8 @@ velocity/misc/timer.py,sha256=wMbV-1yNXeCJo_UPi5sTSslu9hPzokLaIKgd98tyG_4,536
33
32
  velocity/misc/conv/__init__.py,sha256=-caOuiqo0mzjP30Rh-3T0bSlt4M-SzJ4SPr2COk9wmg,39
34
33
  velocity/misc/conv/iconv.py,sha256=V-PcpDXq7wCmyxZ3sXfzpmVH5Nc9OHScvMH26K7N3bI,4375
35
34
  velocity/misc/conv/oconv.py,sha256=TGC6vTcOACtwp_Gpce33ZiVmgqBYQnwBcMNQ1MP6Qdc,4121
36
- velocity_python-0.0.27.dist-info/LICENSE,sha256=aoN245GG8s9oRUU89KNiGTU4_4OtnNmVi4hQeChg6rM,1076
37
- velocity_python-0.0.27.dist-info/METADATA,sha256=4RwnXRYoo73mA4qpLyZgPRA3uRXtpajPGFmDd6hL1os,8522
38
- velocity_python-0.0.27.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
39
- velocity_python-0.0.27.dist-info/top_level.txt,sha256=JW2vJPmodgdgSz7H6yoZvnxF8S3fTMIv-YJWCT1sNW0,9
40
- velocity_python-0.0.27.dist-info/RECORD,,
35
+ velocity_python-0.0.29.dist-info/LICENSE,sha256=aoN245GG8s9oRUU89KNiGTU4_4OtnNmVi4hQeChg6rM,1076
36
+ velocity_python-0.0.29.dist-info/METADATA,sha256=waMEshl4l17tG_tx62zRXVypL1b5aSzjUls8q9JwFPM,8522
37
+ velocity_python-0.0.29.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
38
+ velocity_python-0.0.29.dist-info/top_level.txt,sha256=JW2vJPmodgdgSz7H6yoZvnxF8S3fTMIv-YJWCT1sNW0,9
39
+ velocity_python-0.0.29.dist-info/RECORD,,
@@ -1,558 +0,0 @@
1
-
2
- import decimal
3
- import datetime
4
- import re
5
- from velocity.db import exceptions
6
-
7
- class Query(str):
8
- pass
9
-
10
- class SQL(object):
11
- server = "Generic SQL"
12
- type_column_identifier = 'data_type'
13
- default_schema = 'schema'
14
- lquote = '"'
15
- rquote = '"'
16
-
17
- DatabaseMissingErrorCodes = []
18
- TableMissingErrorCodes = []
19
- ColumnMissingErrorCodes = []
20
- ForeignKeyMissingErrorCodes =[]
21
-
22
- ConnectionErrorCodes = []
23
- DuplicateKeyErrorCodes = []
24
- RetryTransactionCodes = []
25
- TruncationErrorCodes = []
26
- LockTimeoutErrorCodes = []
27
- DatabaseObjectExistsErrorCodes = []
28
-
29
- @classmethod
30
- def quote(self, data):
31
- if isinstance(data, list):
32
- new = []
33
- for item in data:
34
- new.append(self.quote(item))
35
- return new
36
- else:
37
- parts = data.split('.')
38
- new = []
39
- for part in parts:
40
- if self.lquote in part:
41
- new.append(part)
42
- elif part.upper() in reserved_words:
43
- new.append(self.lquote+part+self.rquote)
44
- elif re.findall('[/]',part):
45
- new.append(self.lquote+part+self.rquote)
46
- else:
47
- new.append(part)
48
- return '.'.join(new)
49
-
50
- @classmethod
51
- def version(cls):
52
- return "select @@version"
53
-
54
- @classmethod
55
- def timestamp(cls):
56
- return "select current_timestamp"
57
-
58
- @classmethod
59
- def user(cls):
60
- return "select current_user"
61
-
62
- @classmethod
63
- def databases(cls):
64
- return "select name from master.dbo.sysdatabases"
65
-
66
- @classmethod
67
- def schemas(cls):
68
- return 'select schema_name from information_schema.schemata'
69
-
70
- @classmethod
71
- def current_schema(cls):
72
- return 'select schema_name()'
73
-
74
- @classmethod
75
- def current_database(cls):
76
- return 'select db_name() as current_database'
77
-
78
- @classmethod
79
- def tables(cls, system=False):
80
- return """
81
- select table_schema, table_name
82
- from information_schema.tables
83
- where table_type = 'BASE TABLE'
84
- order by table_schema,table_name
85
- """
86
-
87
- @classmethod
88
- def views(cls, system=False):
89
- return """
90
- select table_schema, table_name
91
- from information_schema.views
92
- order by table_schema,table_name
93
- """
94
-
95
- @classmethod
96
- def __has_pointer(cls,columns):
97
- if columns:
98
- if isinstance(columns,list):
99
- columns = ','.join(columns)
100
- if '>' in columns:
101
- return True
102
- return False
103
-
104
- @classmethod
105
- def select(cls,columns=None,table=None,where=None,orderby=None,groupby=None,having=None,start=None,qty=None):
106
- if cls.__has_pointer(columns):
107
- if isinstance(columns,str):
108
- columns = columns.split(',')
109
- letter = 65
110
- tables = {table: chr(letter)}
111
- letter += 1
112
- __select = []
113
- __from = ['{} AS {}'.format(self.quote(table),tables.get(table))]
114
- __left_join = []
115
-
116
- for column in columns:
117
- if '>' in column:
118
- parts = column.split('>')
119
- foreign = self.GetForeignKeyInfo(parts[0])
120
- ref_table = foreign[0]['referenced_table_name']
121
- ref_schema = foreign[0]['referenced_table_schema']
122
- ref_column = foreign[0]['referenced_column_name']
123
- lookup = "{}:{}".format(ref_table,parts[0])
124
- if lookup in tables:
125
- __select.append('{}."{}" as "{}"'.format(tables.get(lookup),parts[1],'_'.join(parts)))
126
- else:
127
- tables[lookup] = chr(letter)
128
- letter += 1
129
- __select.append('{}."{}" as "{}"'.format(tables.get(lookup),parts[1],'_'.join(parts)))
130
- __left_join.append('LEFT OUTER JOIN "{}"."{}" AS {}'.format(ref_schema,ref_table,tables.get(lookup)))
131
- __left_join.append('ON {}."{}" = {}."{}"'.format(
132
- tables.get(table),
133
- parts[0],
134
- tables.get(lookup),
135
- ref_column
136
- ))
137
- if orderby and column in orderby:
138
- orderby = orderby.replace(column,"{}.{}".format(tables.get(lookup),parts[1]))
139
- else:
140
- if '(' in column:
141
- __select.append(column)
142
- else:
143
- __select.append("{}.{}".format(tables.get(self.table),column))
144
- sql = ['SELECT']
145
- sql.append(','.join(__select))
146
- sql.append('FROM')
147
- sql.extend(__from)
148
- sql.extend(__left_join)
149
- else:
150
- if columns:
151
- if isinstance(columns,str):
152
- columns = columns.split(',')
153
- if isinstance(columns,list):
154
- columns = self.quote(columns)
155
- columns = ','.join(columns)
156
- else:
157
- columns = '*'
158
- sql = [
159
- 'SELECT',
160
- columns,
161
- 'FROM',
162
- self.quote(table),
163
- ]
164
- values = []
165
- if where:
166
- sql.append('WHERE')
167
- if isinstance(where,dict):
168
- join = ''
169
- for key in sorted(where.keys()):
170
- if join: sql.append(join)
171
- if where[key] == None:
172
- sql.append('{} is NULL'.format(self.quote(key.lower())))
173
- else:
174
- sql.append('{} = %s'.format(self.quote(key.lower())))
175
- values.append(where[key])
176
- join = 'AND'
177
- else:
178
- sql.append(where)
179
- if groupby:
180
- sql.append('GROUP BY')
181
- sql.append(groupby)
182
- if having:
183
- sql.append('HAVING')
184
- sql.append(having)
185
- if orderby:
186
- sql.append('ORDER BY')
187
- sql.append(orderby)
188
- if start and qty:
189
- sql.append('OFFSET {} ROWS FETCH NEXT {} ROWS ONLY'.format(start,qty))
190
- elif start:
191
- sql.append('OFFSET {} ROWS'.format(start))
192
- elif qty:
193
- sql.append('FETCH {} ROWS ONLY'.format(qty))
194
- sql = ' '.join(sql)
195
- values = cls.massage_values(values)
196
- return sql, values
197
-
198
- @classmethod
199
- def create_database(cls, name):
200
- return 'create database ' + name
201
-
202
- @classmethod
203
- def drop_database(cls, name):
204
- return 'drop database ' + name
205
-
206
- @classmethod
207
- def create_table(cls, name, columns={}, drop=False):
208
- if '.' in name:
209
- fqtn = name
210
- else:
211
- fqtn = cls.default_schema + name
212
- schema,table = fqtn.split('.')
213
- name = fqtn.replace('.','_')
214
- trigger = 'on_update_row_{0}'.format(name)
215
- sql = []
216
- sql.append('DECLARE @script1 nVarChar(MAX);')
217
- sql.append('DECLARE @script2 nVarChar(MAX);')
218
- if drop:
219
- sql.append(cls.drop_table(fqtn))
220
- sql.append("""
221
- SET @script1 = '
222
- CREATE TABLE {0} (
223
- sys_id int identity(1000,1) primary key,
224
- sys_modified datetime not null default(getdate()),
225
- sys_created datetime not null default(getdate())
226
- )'
227
- """.format(fqtn, table, trigger))
228
- sql.append("""
229
- SET @script2 = '
230
- CREATE TRIGGER {2}
231
- ON {0}
232
- AFTER UPDATE
233
- AS
234
- BEGIN
235
- UPDATE t
236
- SET t.sys_modified = CURRENT_TIMESTAMP,
237
- t.sys_created = d.sys_created
238
- FROM {0} AS t
239
- INNER JOIN deleted AS d on t.sys_id=i.sys_id
240
- END'
241
- """.format(fqtn, table, trigger))
242
- sql.append('EXEC (@script1);')
243
- sql.append('EXEC (@script2);')
244
- for key,val in columns.items():
245
- sql.append("ALTER TABLE {} ADD COLUMN {} {};".format(fqtn,key,cls.get_type(val)))
246
- return '\n\t'.join(sql)
247
-
248
- @classmethod
249
- def drop_table(cls, name):
250
- return "IF OBJECT_ID('%s', 'U') IS NOT NULL DROP TABLE %s;" % (self.quote(name),self.quote(name))
251
-
252
- @classmethod
253
- def columns(cls, name):
254
- if '.' in name:
255
- return """
256
- select column_name
257
- from information_schema.columns
258
- where UPPER(table_schema ) = UPPER(%s)
259
- and UPPER(table_name) = UPPER(%s)
260
- """, tuple(name.split('.'))
261
- else:
262
- return """
263
- select column_name
264
- from information_schema.columns
265
- where UPPER(table_name) = UPPER(%s)
266
- """, tuple([name])
267
-
268
- @classmethod
269
- def column_info(cls, table, name):
270
- params = table.split('.')
271
- params.append(name)
272
- if '.' in table:
273
- return """
274
- select *
275
- from information_schema.columns
276
- where UPPER(table_schema ) = UPPER(%s)
277
- and UPPER(table_name) = UPPER(%s)
278
- and UPPER(column_name) = UPPER(%s)
279
- """, tuple(params)
280
- else:
281
- return """
282
- select *
283
- from information_schema.columns
284
- where UPPER(table_name) = UPPER(%s)
285
- and UPPER(column_name) = UPPER(%s)
286
- """, tuple(params)
287
-
288
-
289
- @classmethod
290
- def primary_keys(cls, table):
291
- params = table.split('.')
292
- if '.' in table:
293
- return """
294
- SELECT COLUMN_NAME
295
- FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
296
- WHERE OBJECTPROPERTY(OBJECT_ID(CONSTRAINT_SCHEMA + '.' + QUOTENAME(CONSTRAINT_NAME)), 'IsPrimaryKey') = 1
297
- AND UPPER(table_schema ) = UPPER(%s) AND UPPER(table_name) = UPPER(%s)
298
- """, tuple(params)
299
- else:
300
- return """
301
- SELECT COLUMN_NAME
302
- FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
303
- WHERE OBJECTPROPERTY(OBJECT_ID(CONSTRAINT_SCHEMA + '.' + QUOTENAME(CONSTRAINT_NAME)), 'IsPrimaryKey') = 1
304
- AND UPPER(table_name) = UPPER(%s)
305
- """, tuple(params)
306
-
307
- @classmethod
308
- def xforeign_keys(cls, table):
309
- params = table.split('.')
310
- if '.' in table:
311
- return """
312
- SELECT COLUMN_NAME
313
- FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
314
- WHERE OBJECTPROPERTY(OBJECT_ID(CONSTRAINT_SCHEMA + '.' + QUOTENAME(CONSTRAINT_NAME)), 'IsPrimaryKey') = 1
315
- AND UPPER(table_schema ) = UPPER(%s) AND UPPER(table_name) = UPPER(%s)
316
- """, tuple(params)
317
- else:
318
- return """
319
- SELECT COLUMN_NAME
320
- FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
321
- WHERE OBJECTPROPERTY(OBJECT_ID(CONSTRAINT_SCHEMA + '.' + QUOTENAME(CONSTRAINT_NAME)), 'IsPrimaryKey') = 1
322
- AND UPPER(table_name) = UPPER(%s)
323
- """, tuple(params)
324
-
325
- @classmethod
326
- def insert(cls, table, data={}):
327
- keys = []
328
- vals = []
329
- args = []
330
- for key,val in data.items():
331
- keys.append(self.quote(key.lower()))
332
- if isinstance(val,str) \
333
- and len(val) > 2 \
334
- and val[:2] == '@@':
335
- vals.append(val[2:])
336
- else:
337
- vals.append('%s')
338
- args.append(val)
339
-
340
- sql = ['INSERT INTO']
341
- sql.append(self.quote(table))
342
- sql.append('(')
343
- sql.append(','.join(keys))
344
- sql.append(')')
345
- sql.append('VALUES')
346
- sql.append('(')
347
- sql.append(','.join(vals))
348
- sql.append(')')
349
- sql = ' '.join(sql)
350
- values = cls.massage_values(args)
351
- return sql,values
352
-
353
- @classmethod
354
- def get_type(cls, v):
355
- if isinstance(v, str):
356
- if v[:2] == '@@':
357
- return v[2:]
358
- elif isinstance(v, str) \
359
- or v is str:
360
- return cls.TYPES.TEXT
361
- elif isinstance(v, bool) \
362
- or v is bool:
363
- return cls.TYPES.BOOLEAN
364
- elif isinstance(v, int) \
365
- or v is int:
366
- if v > 2147483647 or v < -2147483648:
367
- return cls.TYPES.BIGINT
368
- else:
369
- return cls.TYPES.INTEGER
370
- elif isinstance(v, float) \
371
- or v is float:
372
- return cls.TYPES.NUMERIC + '(19, 6)'
373
- elif isinstance(v, decimal.Decimal) \
374
- or v is decimal.Decimal:
375
- return cls.TYPES.NUMERIC + '(19, 6)'
376
- elif isinstance (v, datetime.datetime) \
377
- or v is datetime.datetime:
378
- return cls.TYPES.DATETIME
379
- elif isinstance (v, datetime.date) \
380
- or v is datetime.date:
381
- return cls.TYPES.DATE
382
- elif isinstance(v, datetime.time) \
383
- or v is datetime.time:
384
- return cls.TYPES.TIME
385
- elif isinstance (v, bytes) \
386
- or v is bytes:
387
- return cls.TYPES.BINARY
388
- # Everything else defaults to TEXT, incl. None
389
- return cls.TYPES.TEXT
390
-
391
- @classmethod
392
- def py_type(cls, v):
393
- v = str(v).upper()
394
- if v == cls.TYPES.INTEGER:
395
- return int
396
- elif v in cls.TYPES.TEXT:
397
- return str
398
- elif v == cls.TYPES.BOOLEAN:
399
- return bool
400
- elif v == cls.TYPES.DATE:
401
- return datetime.date
402
- elif v == cls.TYPES.TIME:
403
- return datetime.time
404
- elif v == cls.TYPES.DATETIME:
405
- return datetime.datetime
406
- else:
407
- raise Exception("unmapped type %s" % v)
408
-
409
- @classmethod
410
- def massage_data(cls,data):
411
- """
412
-
413
- :param :
414
- :param :
415
- :param :
416
- :returns:
417
- """
418
- data = {key.lower():val for key,val in data.items()}
419
- primaryKey = set(cls.GetPrimaryKeyColumnNames())
420
- if not primaryKey:
421
- if not cls.Exists():
422
- raise exceptions.DbTableMissingError
423
- dataKeys = set(data.keys()).intersection( primaryKey )
424
- dataColumns = set(data.keys()).difference( primaryKey )
425
- pk = {}
426
- pk.update([(k,data[k]) for k in dataKeys])
427
- d = {}
428
- d.update([(k,data[k]) for k in dataColumns])
429
- return d,pk
430
-
431
- @classmethod
432
- def massage_values(cls, values):
433
- return tuple(values)
434
-
435
- @classmethod
436
- def alter_add(cls, table, columns, null_allowed=True):
437
- sql = []
438
- null = 'NOT NULL' if not null_allowed else ''
439
- if isinstance(columns,dict):
440
- for key,val in columns.items():
441
- sql.append("ALTER TABLE {} ADD {} {} {};".format(self.quote(table), self.quote(key), cls.get_type(val), null))
442
- return '\n\t'.join(sql)
443
-
444
- @classmethod
445
- def alter_drop(cls, table, columns):
446
- sql = ["ALTER TABLE {} DROP COLUMN".format(self.quote(table))]
447
- if isinstance(columns,dict):
448
- for key,val in columns.items():
449
- sql.append("{},".format(key))
450
- if sql[-1][-1] == ',':
451
- sql[-1] = sql[-1][:-1]
452
- return '\n\t'.join(sql)
453
-
454
- @classmethod
455
- def alter_column_by_type(cls, table, column, value, null_allowed=True):
456
- sql = ["ALTER TABLE {} ALTER COLUMN".format(self.quote(table))]
457
- sql.append("{} {}".format(self.quote(column), cls.get_type(value)))
458
- if not null_allowed:
459
- sql.append('NOT NULL')
460
- return '\n\t'.join(sql)
461
-
462
- @classmethod
463
- def alter_column_by_sql(cls, table, column, value):
464
- sql = ["ALTER TABLE {} ALTER COLUMN".format(self.quote(table))]
465
- sql.append("{} {}".format(self.quote(column), value))
466
- return ' '.join(sql)
467
-
468
-
469
- @classmethod
470
- def rename_column(cls, table, name, new):
471
- if '.' in table:
472
- schema, table = table.split('.')
473
- else:
474
- schema = cls.default_schema
475
- return "sp_rename '{}.{}.{}', '{}', 'COLUMN';".format(self.quote(schema), self.quote(table), self.quote(name), new)
476
-
477
- @classmethod
478
- def rename_table(cls, table, name, new):
479
- if '.' in table:
480
- schema, table = table.split('.')
481
- else:
482
- schema = cls.default_schema
483
- return "sp_rename '{}.{}', '{}';".format(self.quote(schema), self.quote(name), new)
484
-
485
- @classmethod
486
- def create_savepoint(cls, sp):
487
- return None #"SAVE TRANSACTION {}".format(sp)
488
-
489
- @classmethod
490
- def release_savepoint(cls, sp):
491
- return None
492
-
493
- @classmethod
494
- def rollback_savepoint(cls, sp):
495
- return None #"ROLLBACK TRANSACTION {}".format(sp)
496
-
497
- @classmethod
498
- def find_duplicates(cls, table, columns, key):
499
- if isinstance(columns, str):
500
- columns = [columns]
501
- return """
502
- SELECT {2}
503
- FROM (SELECT {2},
504
- ROW_NUMBER() OVER (partition BY {1} ORDER BY {2}) AS rnum
505
- FROM {0}) t
506
- WHERE t.rnum > 1;
507
- """.format(table, ','.join(self.quote(columns)), key), tuple()
508
-
509
- @classmethod
510
- def delete_duplicates(cls, table, columns, key):
511
- if isinstance(columns, str):
512
- columns = [columns]
513
- return """
514
- DELETE FROM {0}
515
- WHERE {2} IN (SELECT {2}
516
- FROM (SELECT {2},
517
- ROW_NUMBER() OVER (partition BY {1} ORDER BY {2}) AS rnum
518
- FROM {0}) t
519
- WHERE t.rnum > 1);
520
- """.format(table, ','.join(self.quote(columns)), key), tuple()
521
-
522
- @classmethod
523
- def delete(cls, table, where):
524
- sql = ['DELETE FROM {}'.format(table)]
525
- sql.append('WHERE')
526
- values = []
527
- if isinstance(where,dict):
528
- join = ''
529
- for key in sorted(where.keys()):
530
- if join: sql.append(join)
531
- if where[key] == None:
532
- sql.append('{} is NULL'.format(self.quote(key.lower())))
533
- else:
534
- sql.append('{} = %s'.format(self.quote(key.lower())))
535
- values.append(where[key])
536
- join = 'AND'
537
- else:
538
- sql.append(where)
539
- return ' '.join(sql), tuple(values)
540
-
541
- @classmethod
542
- def truncate(cls, table):
543
- return "truncate table {}".format(self.quote(table)), tuple()
544
-
545
-
546
- class TYPES(object):
547
- TEXT = 'VARCHAR(MAX)'
548
- INTEGER = 'INT'
549
- NUMERIC = 'NUMERIC'
550
- DATETIME = 'DATETIME'
551
- TIMESTAMP = 'DATETIME'
552
- DATE = 'DATE'
553
- TIME = 'TIME'
554
- BIGINT = 'BIGINT'
555
- BOOLEAN = 'BIT'
556
- BINARY = 'VARBINARY(MAX)'
557
-
558
- reserved_words = ['ABSOLUTE', 'ACTION', 'ADA', 'ADD', 'ALL', 'ALLOCATE', 'ALTER', 'AND', 'ANY', 'ARE', 'AS', 'ASC', 'ASSERTION', 'AT', 'AUTHORIZATION', 'AVG', 'BACKUP', 'BEGIN', 'BETWEEN', 'BIT', 'BIT_LENGTH', 'BOTH', 'BREAK', 'BROWSE', 'BULK', 'BY', 'CASCADE', 'CASCADED', 'CASE', 'CAST', 'CATALOG', 'CHAR', 'CHARACTER', 'CHARACTER_LENGTH', 'CHAR_LENGTH', 'CHECK', 'CHECKPOINT', 'CLOSE', 'CLUSTERED', 'COALESCE', 'COLLATE', 'COLLATION', 'COLUMN', 'COMMIT', 'COMPUTE', 'CONNECT', 'CONNECTION', 'CONSTRAINT', 'CONSTRAINTS', 'CONTAINS', 'CONTAINSTABLE', 'CONTINUE', 'CONVERT', 'CORRESPONDING', 'COUNT', 'CREATE', 'CROSS', 'CURRENT', 'CURRENT_DATE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURRENT_USER', 'CURSOR', 'DATABASE', 'DATE', 'DAY', 'DBCC', 'DEALLOCATE', 'DEC', 'DECIMAL', 'DECLARE', 'DEFAULT', 'DEFERRABLE', 'DEFERRED', 'DELETE', 'DENY', 'DESC', 'DESCRIBE', 'DESCRIPTOR', 'DIAGNOSTICS', 'DISCONNECT', 'DISK', 'DISTINCT', 'DISTRIBUTED', 'DOMAIN', 'DOUBLE', 'DROP', 'DUMP', 'ELSE', 'END', 'END-EXEC', 'ERRLVL', 'ESCAPE', 'EXCEPT', 'EXCEPTION', 'EXEC', 'EXECUTE', 'EXISTS', 'EXIT', 'EXTERNAL', 'EXTRACT', 'FALSE', 'FETCH', 'FILE', 'FILLFACTOR', 'FIRST', 'FLOAT', 'FOR', 'FOREIGN', 'FORTRAN', 'FOUND', 'FREETEXT', 'FREETEXTTABLE', 'FROM', 'FULL', 'FUNCTION', 'GET', 'GLOBAL', 'GO', 'GOTO', 'GRANT', 'GROUP', 'HAVING', 'HOLDLOCK', 'HOUR', 'IDENTITY', 'IDENTITYCOL', 'IDENTITY_INSERT', 'IF', 'IMMEDIATE', 'IN', 'INCLUDE', 'INDEX', 'INDICATOR', 'INITIALLY', 'INNER', 'INPUT', 'INSENSITIVE', 'INSERT', 'INT', 'INTEGER', 'INTERSECT', 'INTERVAL', 'INTO', 'IS', 'ISOLATION', 'JOIN', 'KEY', 'KILL', 'LANGUAGE', 'LAST', 'LEADING', 'LEFT', 'LEVEL', 'LIKE', 'LINENO', 'LOAD', 'LOCAL', 'LOWER', 'MATCH', 'MAX', 'MERGE', 'MIN', 'MINUTE', 'MODULE', 'MONTH', 'NAMES', 'NATIONAL', 'NATURAL', 'NCHAR', 'NEXT', 'NO', 'NOCHECK', 'NONCLUSTERED', 'NONE', 'NOT', 'NULL', 'NULLIF', 'NUMERIC', 'OCTET_LENGTH', 'OF', 'OFF', 'OFFSETS', 'ON', 'ONLY', 'OPEN', 'OPENDATASOURCE', 'OPENQUERY', 'OPENROWSET', 'OPENXML', 'OPTION', 'OR', 'ORDER', 'OUTER', 'OUTPUT', 'OVER', 'OVERLAPS', 'PAD', 'PARTIAL', 'PASCAL', 'PERCENT', 'PIVOT', 'PLAN', 'POSITION', 'PRECISION', 'PREPARE', 'PRESERVE', 'PRIMARY', 'PRINT', 'PRIOR', 'PRIVILEGES', 'PROC', 'PROCEDURE', 'PUBLIC', 'RAISERROR', 'READ', 'READTEXT', 'REAL', 'RECONFIGURE', 'REFERENCES', 'RELATIVE', 'REPLICATION', 'RESTORE', 'RESTRICT', 'RETURN', 'REVERT', 'REVOKE', 'RIGHT', 'ROLLBACK', 'ROWCOUNT', 'ROWGUIDCOL', 'ROWS', 'RULE', 'SAVE', 'SCHEMA', 'SCROLL', 'SECOND', 'SECTION', 'SECURITYAUDIT', 'SELECT', 'SEMANTICKEYPHRASETABLE', 'SEMANTICSIMILARITYDETAILSTABLE', 'SEMANTICSIMILARITYTABLE', 'SESSION', 'SESSION_USER', 'SET', 'SETUSER', 'SHUTDOWN', 'SIZE', 'SMALLINT', 'SOME', 'SPACE', 'SQL', 'SQLCA', 'SQLCODE', 'SQLERROR', 'SQLSTATE', 'SQLWARNING', 'STATISTICS', 'SUBSTRING', 'SUM', 'SYSTEM_USER', 'TABLE', 'TABLESAMPLE', 'TEMPORARY', 'TEXTSIZE', 'THEN', 'TIME', 'TIMESTAMP', 'TIMEZONE_HOUR', 'TIMEZONE_MINUTE', 'TO', 'TOP', 'TRAILING', 'TRAN', 'TRANSACTION', 'TRANSLATE', 'TRANSLATION', 'TRIGGER', 'TRIM', 'TRUE', 'TRUNCATE', 'TRY_CONVERT', 'TSEQUAL', 'UNION', 'UNIQUE', 'UNKNOWN', 'UNPIVOT', 'UPDATE', 'UPDATETEXT', 'UPPER', 'USAGE', 'USE', 'USER', 'USING', 'VALUE', 'VALUES', 'VARCHAR', 'VARYING', 'VIEW', 'WAITFOR', 'WHEN', 'WHENEVER', 'WHERE', 'WHILE', 'WITH', 'WITHIN GROUP', 'WORK', 'WRITE', 'WRITETEXT', 'YEAR', 'ZONE',]