dbobj3 0.5.0__tar.gz → 0.7.0__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.
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dbobj3"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.7.0"
|
|
8
8
|
description = "High-level MySQL/MSSQL/Oracle access module"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.6"
|
|
@@ -16,7 +16,7 @@ dependencies = [
|
|
|
16
16
|
packages = ["src/dbobj3.py"]
|
|
17
17
|
|
|
18
18
|
[tool.bumpversion]
|
|
19
|
-
current_version = "0.
|
|
19
|
+
current_version = "0.7.0"
|
|
20
20
|
commit = true
|
|
21
21
|
tag = true
|
|
22
22
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)"
|
|
@@ -21,7 +21,7 @@ Example:
|
|
|
21
21
|
rsServices.next()
|
|
22
22
|
|
|
23
23
|
"""
|
|
24
|
-
__version__ = "0.
|
|
24
|
+
__version__ = "0.7.0"
|
|
25
25
|
|
|
26
26
|
from sys import version as sys_version, exit
|
|
27
27
|
pyversion = sys_version[0:sys_version.find(' ')]
|
|
@@ -33,9 +33,9 @@ try:
|
|
|
33
33
|
import MySQLdb
|
|
34
34
|
import MySQLdb.cursors
|
|
35
35
|
import MySQLdb.converters
|
|
36
|
-
# MySQLdb dropped Python3.x support
|
|
37
|
-
# - For Centos/Python2.x use
|
|
38
|
-
# - yum install mysql-devel, MySQL-python
|
|
36
|
+
# MySQLdb dropped Python3.x support
|
|
37
|
+
# - For Centos/Python2.x use
|
|
38
|
+
# - yum install mysql-devel, MySQL-python
|
|
39
39
|
# - pip install mysql-python
|
|
40
40
|
# - For Python3.x use the fork MySQLdb
|
|
41
41
|
# - pip install mysqlclient ( developed by pymysql devs )
|
|
@@ -53,7 +53,7 @@ if not using_mysqlclient:
|
|
|
53
53
|
import MySQLdb.converters
|
|
54
54
|
# Windows:
|
|
55
55
|
#import pymysql
|
|
56
|
-
#pymysql.install_as_MySQLdb()
|
|
56
|
+
#pymysql.install_as_MySQLdb()
|
|
57
57
|
#import pymysql.cursors
|
|
58
58
|
#import pymysql.converters
|
|
59
59
|
using_pymysql = True
|
|
@@ -95,9 +95,15 @@ try:
|
|
|
95
95
|
import requests
|
|
96
96
|
lstLoadedDrivers.append({"requests": "Loaded (API)"})
|
|
97
97
|
except ImportError:
|
|
98
|
-
#print('could not import
|
|
98
|
+
#print('could not import requests')
|
|
99
99
|
lstLoadedDrivers.append({"requests": "Not Loaded (API)"})
|
|
100
100
|
|
|
101
|
+
try:
|
|
102
|
+
import jaydebeapi
|
|
103
|
+
lstLoadedDrivers.append({"jaydebeapi": "Loaded (JDBC)"})
|
|
104
|
+
except ImportError:
|
|
105
|
+
lstLoadedDrivers.append({"jaydebeapi": "Not Loaded (JDBC)"})
|
|
106
|
+
|
|
101
107
|
try:
|
|
102
108
|
import json
|
|
103
109
|
except ImportError:
|
|
@@ -156,6 +162,8 @@ class dbObjCursor:
|
|
|
156
162
|
self.createProgress()
|
|
157
163
|
elif(prmDBType=="API"):
|
|
158
164
|
self.createAPI()
|
|
165
|
+
elif(prmDBType=="JDBC"):
|
|
166
|
+
self.createJDBC()
|
|
159
167
|
|
|
160
168
|
def createMySql(self):
|
|
161
169
|
self.cursor = self.connection.cursor(MySQLdb.cursors.DictCursor)
|
|
@@ -177,6 +185,9 @@ class dbObjCursor:
|
|
|
177
185
|
def createAPI(self):
|
|
178
186
|
self.lstRecords = []
|
|
179
187
|
|
|
188
|
+
def createJDBC(self):
|
|
189
|
+
self.cursor = self.connection.cursor()
|
|
190
|
+
|
|
180
191
|
def moveNext(self):
|
|
181
192
|
"""Same as next"""
|
|
182
193
|
self.next()
|
|
@@ -195,6 +206,8 @@ class dbObjCursor:
|
|
|
195
206
|
self.progressNext()
|
|
196
207
|
elif(self.dbType == "API"):
|
|
197
208
|
self.apiNext()
|
|
209
|
+
elif(self.dbType == "JDBC"):
|
|
210
|
+
self.jdbcNext()
|
|
198
211
|
|
|
199
212
|
def mySqlNext(self):
|
|
200
213
|
resultSet = self.cursor.fetchone()
|
|
@@ -275,6 +288,22 @@ class dbObjCursor:
|
|
|
275
288
|
else:
|
|
276
289
|
self.EOF = 1
|
|
277
290
|
|
|
291
|
+
def jdbcNext(self):
|
|
292
|
+
try:
|
|
293
|
+
resultSet = self.cursor.fetchone()
|
|
294
|
+
except Exception as e:
|
|
295
|
+
print(e)
|
|
296
|
+
self.EOF = 1
|
|
297
|
+
return
|
|
298
|
+
if(resultSet != None):
|
|
299
|
+
columns = [column[0] for column in self.cursor.description]
|
|
300
|
+
self.fieldByName = (dict(zip(columns, resultSet)))
|
|
301
|
+
#self.fieldNames.append(cursorFieldname[0])
|
|
302
|
+
self.fields = self.fieldByName
|
|
303
|
+
self.EOF = 0
|
|
304
|
+
else:
|
|
305
|
+
self.EOF = 1
|
|
306
|
+
|
|
278
307
|
def first(self):
|
|
279
308
|
"""Move to the next record in the record set and loads the data into the fields property. Sets EOF at end of records."""
|
|
280
309
|
if(self.dbType == "MYSQL"):
|
|
@@ -323,24 +352,34 @@ class dbObjCursor:
|
|
|
323
352
|
self.recordPointer = 1
|
|
324
353
|
#print('progressExecute (fetchs all) time.time()-t0: ',str(round(time.time()-t0,3)),' seconds')
|
|
325
354
|
|
|
355
|
+
def jdbcExecute(self, prmSql):
|
|
356
|
+
self.cursor.execute(prmSql)
|
|
357
|
+
self.lstRecords = self.cursor.fetchall()
|
|
358
|
+
self.numRows = len(self.lstRecords)
|
|
359
|
+
self.numFields = len(self.cursor.description)
|
|
360
|
+
if(self.numRows > 0):
|
|
361
|
+
self.recordPointer = 1
|
|
362
|
+
|
|
326
363
|
class dbObjConnection:
|
|
327
364
|
"""
|
|
328
365
|
dbObjConnection is the database connection object. It is responsible for connecting to
|
|
329
366
|
the database. This object supports access to MySQL, Microsoft SQL Server, Oracle,
|
|
330
367
|
SQLite3, and Progress DataDirect.
|
|
331
|
-
|
|
332
|
-
prmDBType can be: MYSQL, MSSQL, ORACLE, SQLITE3, PROGRESS, or
|
|
368
|
+
|
|
369
|
+
prmDBType can be: MYSQL, MSSQL, ORACLE, SQLITE3, PROGRESS, API, or JDBC
|
|
370
|
+
|
|
333
371
|
"""
|
|
334
|
-
def __init__(self,
|
|
335
|
-
prmDBType="MYSQL",
|
|
336
|
-
prmHost="localhost",
|
|
337
|
-
prmDb="",
|
|
338
|
-
prmUser="",
|
|
339
|
-
prmPass="",
|
|
340
|
-
prmPort=3306,
|
|
341
|
-
envOracle={},
|
|
372
|
+
def __init__(self,
|
|
373
|
+
prmDBType="MYSQL",
|
|
374
|
+
prmHost="localhost",
|
|
375
|
+
prmDb="",
|
|
376
|
+
prmUser="",
|
|
377
|
+
prmPass="",
|
|
378
|
+
prmPort=3306,
|
|
379
|
+
envOracle={},
|
|
342
380
|
envProgress={},
|
|
343
381
|
driver='',
|
|
382
|
+
driverClass="",
|
|
344
383
|
prmApiBaseUrl="",
|
|
345
384
|
prmApiKey="",
|
|
346
385
|
prmApiKeyName="sk"):
|
|
@@ -355,6 +394,7 @@ class dbObjConnection:
|
|
|
355
394
|
self.reconnect_attempts = 0
|
|
356
395
|
self.using_pymysql = using_pymysql
|
|
357
396
|
self.drivers = lstLoadedDrivers
|
|
397
|
+
self.driverClass = driverClass
|
|
358
398
|
if(prmDBType == "API"):
|
|
359
399
|
self.apiBaseUrl = prmApiBaseUrl
|
|
360
400
|
self.apiKeyName = prmApiKeyName
|
|
@@ -416,6 +456,8 @@ class dbObjConnection:
|
|
|
416
456
|
return self.sqlite3Connect(prmDb)
|
|
417
457
|
elif(self.dbType == "PROGRESS"):
|
|
418
458
|
return self.progressConnect(prmHost, prmDb, prmUser, prmPass, prmPort)
|
|
459
|
+
elif(self.dbType == "JDBC"):
|
|
460
|
+
return self.jdbcConnect(prmHost, prmDb, prmUser, prmPass)
|
|
419
461
|
|
|
420
462
|
def setConnectSuccess(self):
|
|
421
463
|
self.reconnect_attempts = 0
|
|
@@ -473,7 +515,7 @@ class dbObjConnection:
|
|
|
473
515
|
self.setConnectFail(e)
|
|
474
516
|
return self.msgObj
|
|
475
517
|
|
|
476
|
-
def progressConnect(self, prmHost, prmDb, prmUser, prmPass, prmPort=
|
|
518
|
+
def progressConnect(self, prmHost, prmDb, prmUser, prmPass, prmPort=35028, envProgress={}, driver=None):
|
|
477
519
|
try:
|
|
478
520
|
driver = driver or self.driver
|
|
479
521
|
strCnxn = 'Driver={};'.format(driver)
|
|
@@ -506,6 +548,18 @@ class dbObjConnection:
|
|
|
506
548
|
self.setConnectSuccess()
|
|
507
549
|
return self.msgObj
|
|
508
550
|
|
|
551
|
+
def jdbcConnect(self, prmConnString, prmDriver, prmUser, prmPass):
|
|
552
|
+
try:
|
|
553
|
+
self.connHandle = jaydebeapi.connect(self.driverClass, prmConnString, [prmUser, prmPass], prmDriver)
|
|
554
|
+
if(self.connHandle):
|
|
555
|
+
self.setConnectSuccess()
|
|
556
|
+
else:
|
|
557
|
+
self.setConnectFail()
|
|
558
|
+
except Exception as e:
|
|
559
|
+
self.setConnectFail(e)
|
|
560
|
+
print(e)
|
|
561
|
+
return self.msgObj
|
|
562
|
+
|
|
509
563
|
def reconnect(self):
|
|
510
564
|
# https://dev.mysql.com/doc/refman/8.0/en/gone-away.html
|
|
511
565
|
mysql_lost_msg = '''
|
|
@@ -516,10 +570,10 @@ class dbObjConnection:
|
|
|
516
570
|
|
|
517
571
|
You may also need to increase the innodb_log_file_size mysql variable in your my.cnf configuration
|
|
518
572
|
to for example 128MB or higher.
|
|
519
|
-
|
|
520
|
-
Server dropped an incorrect or too large packet. If mysqld gets a packet that is too large or
|
|
521
|
-
incorrect, it assumes that something has gone wrong with the client and closes the connection.
|
|
522
|
-
To fix, you can increase the maximal packet size limit max_allowed_packet in my.cnf file,
|
|
573
|
+
|
|
574
|
+
Server dropped an incorrect or too large packet. If mysqld gets a packet that is too large or
|
|
575
|
+
incorrect, it assumes that something has gone wrong with the client and closes the connection.
|
|
576
|
+
To fix, you can increase the maximal packet size limit max_allowed_packet in my.cnf file,
|
|
523
577
|
eg. set max_allowed_packet = 128M, then restart your MySQL server.
|
|
524
578
|
'''
|
|
525
579
|
|
|
@@ -530,16 +584,16 @@ class dbObjConnection:
|
|
|
530
584
|
|
|
531
585
|
self.msgObj.success = False
|
|
532
586
|
|
|
533
|
-
while ( self.autoreconnect
|
|
534
|
-
and( self.reconnect_attempts <= self.reconnect_max )
|
|
587
|
+
while ( self.autoreconnect
|
|
588
|
+
and( self.reconnect_attempts <= self.reconnect_max )
|
|
535
589
|
and not self.msgObj.success ):
|
|
536
|
-
|
|
590
|
+
|
|
537
591
|
self.reconnect_attempts += 1
|
|
538
592
|
if self.reconnect_attempts > self.reconnect_max:
|
|
539
593
|
self.msgObj.message += ' - Exceeded Maximum autoreconnect Attempts to {0} ({1} attempts).'.format(self.dbType, self.reconnect_attempts)
|
|
540
594
|
print(self.msgObj.message)
|
|
541
595
|
return self.msgObj
|
|
542
|
-
|
|
596
|
+
|
|
543
597
|
print("ATTEMPT {0} of Reconnect to {1}".format(self.reconnect_attempts,self.dbType))
|
|
544
598
|
if(self.dbType == "MYSQL"):
|
|
545
599
|
self.mySqlConnect(self.host, self.db, self.user, self.passwd, self.port)
|
|
@@ -551,7 +605,7 @@ class dbObjConnection:
|
|
|
551
605
|
self.sqlite3Connect(self.db)
|
|
552
606
|
elif(self.dbType == "PROGRESS"):
|
|
553
607
|
self.progressConnect(self.host, self.db, self.user, self.passwd, self.port)
|
|
554
|
-
|
|
608
|
+
|
|
555
609
|
if self.msgObj.success:
|
|
556
610
|
print('Connection to {0} Restored.'.format(self.dbType))
|
|
557
611
|
return self.msgObj
|
|
@@ -569,6 +623,8 @@ class dbObjConnection:
|
|
|
569
623
|
return self.progressGetCursor()
|
|
570
624
|
elif(self.dbType == "API"):
|
|
571
625
|
return self.apiGetCursor()
|
|
626
|
+
elif(self.dbType == "JDBC"):
|
|
627
|
+
return self.jdbcGetCursor()
|
|
572
628
|
|
|
573
629
|
def setCursorSuccess(self, cursor):
|
|
574
630
|
if cursor:
|
|
@@ -629,6 +685,14 @@ class dbObjConnection:
|
|
|
629
685
|
except Exception as e:
|
|
630
686
|
self.setCursorFail(e)
|
|
631
687
|
|
|
688
|
+
def jdbcGetCursor(self):
|
|
689
|
+
try:
|
|
690
|
+
cursor = dbObjCursor(self.connHandle, self.dbType)
|
|
691
|
+
self.setCursorSuccess(cursor)
|
|
692
|
+
return cursor
|
|
693
|
+
except Exception as e:
|
|
694
|
+
self.setCursorFail(e)
|
|
695
|
+
|
|
632
696
|
def disconnect(self):
|
|
633
697
|
"""Disconnect the connection handle to the database"""
|
|
634
698
|
if(self.dbType == "MYSQL"):
|
|
@@ -641,6 +705,8 @@ class dbObjConnection:
|
|
|
641
705
|
self.sqlite3Disconnect()
|
|
642
706
|
elif(self.dbType == "PROGRESS"):
|
|
643
707
|
self.progressDisconnect()
|
|
708
|
+
elif(self.dbType == "JDBC"):
|
|
709
|
+
self.jdbcDisconnect()
|
|
644
710
|
|
|
645
711
|
def mySqlDisconnect(self):
|
|
646
712
|
if self.connHandle and self.connHandle.open:
|
|
@@ -669,6 +735,14 @@ class dbObjConnection:
|
|
|
669
735
|
|
|
670
736
|
def apiDisconnect(self):
|
|
671
737
|
pass
|
|
738
|
+
if self.connHandle:
|
|
739
|
+
self.connHandle.close()
|
|
740
|
+
self.connHandle = None
|
|
741
|
+
|
|
742
|
+
def jdbcDisconnect(self):
|
|
743
|
+
if self.connHandle:
|
|
744
|
+
self.connHandle.close()
|
|
745
|
+
self.connHandle = None
|
|
672
746
|
|
|
673
747
|
def execute(self, prmSql, *args):
|
|
674
748
|
"""Execute the SQL and return a record set if applicable"""
|
|
@@ -684,7 +758,31 @@ class dbObjConnection:
|
|
|
684
758
|
return self.progressExecute(prmSql)
|
|
685
759
|
if(self.dbType in ("API")):
|
|
686
760
|
return self.apiExecute(prmSql)
|
|
761
|
+
if(self.dbType in ("JDBC")):
|
|
762
|
+
return self.jdbcExecute(prmSql)
|
|
687
763
|
|
|
764
|
+
def executemany(self, prmSql, *args):
|
|
765
|
+
"""Execute the SQL and return a record set if applicable"""
|
|
766
|
+
if(self.dbType == "MYSQL"):
|
|
767
|
+
return self.mySqlExecuteMany(prmSql, *args)
|
|
768
|
+
if(self.dbType == "MSSQL"):
|
|
769
|
+
return
|
|
770
|
+
#return self.msSqlExecuteMany(prmSql)
|
|
771
|
+
if(self.dbType == "ORACLE"):
|
|
772
|
+
return
|
|
773
|
+
#return self.oracleExecuteMany(prmSql)
|
|
774
|
+
if(self.dbType in ("SQLITE","SQLITE3")):
|
|
775
|
+
return
|
|
776
|
+
#return self.sqlite3ExecuteMany(prmSql)
|
|
777
|
+
if(self.dbType in ("PROGRESS")):
|
|
778
|
+
return
|
|
779
|
+
#return self.progressExecuteMany(prmSql)
|
|
780
|
+
if(self.dbType in ("API")):
|
|
781
|
+
return
|
|
782
|
+
#return self.apiExecuteMany(prmSql)
|
|
783
|
+
if(self.dbType in ("JDBC")):
|
|
784
|
+
return
|
|
785
|
+
#return self.jdbcExecuteMany(prmSql)
|
|
688
786
|
|
|
689
787
|
def fetchall(self, prmSql, *args):
|
|
690
788
|
"""Returns result set as a list of dictionaries"""
|
|
@@ -695,42 +793,35 @@ class dbObjConnection:
|
|
|
695
793
|
crsr.next()
|
|
696
794
|
return rset
|
|
697
795
|
|
|
698
|
-
|
|
699
796
|
def fetchone(self, prmSql, *args):
|
|
700
797
|
"""Returns a single row as a dictionary"""
|
|
701
798
|
crsr = self.execute( prmSql, *args )
|
|
702
799
|
dictRow = {} if crsr.EOF else crsr.fields
|
|
703
800
|
return dictRow
|
|
704
801
|
|
|
705
|
-
|
|
706
802
|
def fetchval(self, prmSql, *args):
|
|
707
803
|
"""Returns a single value"""
|
|
708
804
|
dictRow = self.fetchone( prmSql, *args )
|
|
709
805
|
listVals = list(dictRow.values())
|
|
710
806
|
return None if not listVals else listVals[0]
|
|
711
807
|
|
|
712
|
-
|
|
713
808
|
def fetchlistvals(self, prmSql, *args):
|
|
714
809
|
"""Returns a list of vals; if more than one key/column, returns a list of value tuples"""
|
|
715
810
|
listvals = []
|
|
716
811
|
rset = self.fetchall(prmSql, *args)
|
|
717
812
|
if not rset:
|
|
718
813
|
return []
|
|
719
|
-
keys = list(rset[0].keys())
|
|
720
814
|
for dictRow in rset:
|
|
721
|
-
if len(
|
|
722
|
-
|
|
723
|
-
else:
|
|
724
|
-
listvals.append( tuple( dictRow.get(k) for k in keys ) )
|
|
815
|
+
vals = list(dictRow.values())[0] if len(dictRow.values())==1 else list(dictRow.values())
|
|
816
|
+
listvals.append( vals )
|
|
725
817
|
return listvals
|
|
726
818
|
|
|
727
|
-
|
|
728
819
|
def insert(self, table, prmDict, update_on_duplicate=False):
|
|
729
820
|
if update_on_duplicate:
|
|
730
821
|
keystr = ','.join(prmDict.keys())
|
|
731
822
|
valstr = ','.join(['%s' for i in range(len(prmDict.keys()))])
|
|
732
823
|
setstr = ",".join([ "{k}=%s".format(k=k) for k in prmDict.keys()])
|
|
733
|
-
args = tuple(prmDict.values()) * 2
|
|
824
|
+
args = tuple(prmDict.values()) * 2
|
|
734
825
|
strSql = "INSERT INTO {table} ({keystr}) VALUES ({valstr})".format(table=table,keystr=keystr,valstr=valstr)
|
|
735
826
|
strSql += "ON DUPLICATE KEY UPDATE {setstr}".format(setstr=setstr)
|
|
736
827
|
return self.execute(strSql, *args)
|
|
@@ -752,20 +843,24 @@ class dbObjConnection:
|
|
|
752
843
|
self.mySqlPing()
|
|
753
844
|
# untested
|
|
754
845
|
elif(self.dbType == "MSSQL"):
|
|
755
|
-
|
|
846
|
+
return
|
|
756
847
|
self.msSqlPing()
|
|
757
848
|
# does not work
|
|
758
849
|
elif(self.dbType == "ORACLE"):
|
|
759
|
-
|
|
850
|
+
return
|
|
760
851
|
self.oraclePing()
|
|
761
852
|
# untested
|
|
762
853
|
elif(self.dbType in ("SQLITE", "SQLITE3")):
|
|
763
|
-
|
|
854
|
+
return
|
|
764
855
|
self.sqlite3Ping()
|
|
765
856
|
# untested
|
|
766
857
|
elif(self.dbType == "PROGRESS"):
|
|
767
|
-
|
|
858
|
+
return
|
|
768
859
|
self.progressPing()
|
|
860
|
+
# untested
|
|
861
|
+
elif(self.dbType == "JDBC"):
|
|
862
|
+
return
|
|
863
|
+
self.jdbcPing()
|
|
769
864
|
|
|
770
865
|
def mySqlPing(self, reconnect=True):
|
|
771
866
|
"""
|
|
@@ -837,7 +932,10 @@ class dbObjConnection:
|
|
|
837
932
|
def mySqlExecute(self, prmSql, *args):
|
|
838
933
|
mySqlCursor = self.getCursor()
|
|
839
934
|
try:
|
|
840
|
-
|
|
935
|
+
if args:
|
|
936
|
+
mySqlCursor.cursor.execute(prmSql, args)
|
|
937
|
+
else:
|
|
938
|
+
mySqlCursor.cursor.execute(prmSql)
|
|
841
939
|
self.msgObj.message = "SQL Executed: "+prmSql
|
|
842
940
|
self.msgObj.success = True
|
|
843
941
|
mySqlCursor.numRows = mySqlCursor.cursor.rowcount
|
|
@@ -994,6 +1092,119 @@ class dbObjConnection:
|
|
|
994
1092
|
apiCursor.success = False
|
|
995
1093
|
return apiCursor
|
|
996
1094
|
|
|
1095
|
+
def jdbcExecute(self, prmSql):
|
|
1096
|
+
jdbcCursor = self.getCursor()
|
|
1097
|
+
try:
|
|
1098
|
+
jdbcCursor.cursor.execute(prmSql)
|
|
1099
|
+
self.msgObj.message = "SQL Executed: "+prmSql
|
|
1100
|
+
self.msgObj.success = True
|
|
1101
|
+
except Exception as e:
|
|
1102
|
+
self.msgObj.message = "SQL Failed: "+prmSql+" - "+str(e)
|
|
1103
|
+
self.msgObj.success = False
|
|
1104
|
+
jdbcCursor.numFields = 0
|
|
1105
|
+
jdbcCursor.numRows = 0
|
|
1106
|
+
jdbcCursor.EOF = 1
|
|
1107
|
+
jdbcCursor.success = False
|
|
1108
|
+
print(self.msgObj.message)
|
|
1109
|
+
return jdbcCursor
|
|
1110
|
+
jdbcCursor.next()
|
|
1111
|
+
return jdbcCursor
|
|
1112
|
+
|
|
1113
|
+
def mySqlExecuteMany(self, prmSql, *args):
|
|
1114
|
+
# https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-executemany.html
|
|
1115
|
+
mySqlCursor = self.getCursor()
|
|
1116
|
+
try:
|
|
1117
|
+
mySqlCursor.cursor.executemany(prmSql, *args)
|
|
1118
|
+
self.msgObj.message = "SQL Executed: "+prmSql
|
|
1119
|
+
self.msgObj.success = True
|
|
1120
|
+
mySqlCursor.numRows = mySqlCursor.cursor.rowcount
|
|
1121
|
+
self.lastInsId = self.connHandle.insert_id()
|
|
1122
|
+
except MySQLdb.OperationalError as e:
|
|
1123
|
+
self.msgObj.message += ' - OperationalError: {0}'.format(e)
|
|
1124
|
+
mySqlCursor = self.setMySqlExecuteFail(mySqlCursor, prmSql, e, *args)
|
|
1125
|
+
print(self.msgObj.message)
|
|
1126
|
+
if "server has gone away" in str(e):
|
|
1127
|
+
self.msgObj.message += ' - Lost Connection Due to timeout,'
|
|
1128
|
+
self.msgObj.message += ' innodb_log_file_size, dropped incorrect/large packet,'
|
|
1129
|
+
self.msgObj.message += ' or killed process/connection.'
|
|
1130
|
+
self.msgObj.message += ' connHandle={0}, connHandle.open={1}'.format(self.connHandle,self.connHandle.open)
|
|
1131
|
+
self.reconnect()
|
|
1132
|
+
elif self.connHandle.open==0 or "Can't connect to" in str(e):
|
|
1133
|
+
self.msgObj.message += ' - Database Connection Closed or Never Established.'
|
|
1134
|
+
self.msgObj.message += ' connHandle={0}, connHandle.open={1}'.format(self.connHandle,self.connHandle.open)
|
|
1135
|
+
self.reconnect()
|
|
1136
|
+
return mySqlCursor if not self.msgObj.success else self.mySqlExecute( prmSql, *args )
|
|
1137
|
+
except Exception as e:
|
|
1138
|
+
mySqlCursor = self.setMySqlExecuteFail(mySqlCursor, prmSql, e, *args)
|
|
1139
|
+
if self.connHandle.open==0 or "Can't connect to" in str(e):
|
|
1140
|
+
self.msgObj.message += ' - Database Connection Closed or Never Established.'
|
|
1141
|
+
self.msgObj.message += ' connHandle={0}, connHandle.open={1}'.format(self.connHandle,self.connHandle.open)
|
|
1142
|
+
self.reconnect()
|
|
1143
|
+
return mySqlCursor if not self.msgObj.success else self.mySqlExecute( prmSql, *args )
|
|
1144
|
+
print(self.msgObj.message)
|
|
1145
|
+
return mySqlCursor
|
|
1146
|
+
else:
|
|
1147
|
+
mySqlCursor = self.setMySqlExecuteSuccess(mySqlCursor, prmSql, *args)
|
|
1148
|
+
return mySqlCursor
|
|
1149
|
+
|
|
1150
|
+
def getTransactionIsolation(self):
|
|
1151
|
+
# untested
|
|
1152
|
+
if(self.dbType == "MYSQL"):
|
|
1153
|
+
return
|
|
1154
|
+
self.mySqlGetTransactionIsolation()
|
|
1155
|
+
# will not work
|
|
1156
|
+
elif(self.dbType == "MSSQL"):
|
|
1157
|
+
return
|
|
1158
|
+
self.msSqlGetTransactionIsolation()
|
|
1159
|
+
# untested
|
|
1160
|
+
elif(self.dbType == "ORACLE"):
|
|
1161
|
+
return
|
|
1162
|
+
self.oracleGetTransactionIsolation()
|
|
1163
|
+
# untested
|
|
1164
|
+
elif(self.dbType in ("SQLITE", "SQLITE3")):
|
|
1165
|
+
return
|
|
1166
|
+
self.sqlite3GetTransactionIsolation()
|
|
1167
|
+
# untested
|
|
1168
|
+
elif(self.dbType == "PROGRESS"):
|
|
1169
|
+
return
|
|
1170
|
+
self.progressGetTransactionIsolation()
|
|
1171
|
+
# untested
|
|
1172
|
+
elif(self.dbType == "JDBC"):
|
|
1173
|
+
return self.jdbcGetTransactionIsolation()
|
|
1174
|
+
|
|
1175
|
+
def setTransactionIsolation(self, lvl):
|
|
1176
|
+
# untested
|
|
1177
|
+
if(self.dbType == "MYSQL"):
|
|
1178
|
+
return
|
|
1179
|
+
self.mySqlSetTransactionIsolation(lvl)
|
|
1180
|
+
# will not work
|
|
1181
|
+
elif(self.dbType == "MSSQL"):
|
|
1182
|
+
return
|
|
1183
|
+
self.msSqlSetTransactionIsolation(lvl)
|
|
1184
|
+
# does not work
|
|
1185
|
+
elif(self.dbType == "ORACLE"):
|
|
1186
|
+
return
|
|
1187
|
+
self.oracleSetTransactionIsolation(lvl)
|
|
1188
|
+
# untested
|
|
1189
|
+
elif(self.dbType in ("SQLITE", "SQLITE3")):
|
|
1190
|
+
return
|
|
1191
|
+
self.sqlite3SetTransactionIsolation(lvl)
|
|
1192
|
+
# untested
|
|
1193
|
+
elif(self.dbType == "PROGRESS"):
|
|
1194
|
+
return
|
|
1195
|
+
self.progressSetTransactionIsolation(lvl)
|
|
1196
|
+
# untested
|
|
1197
|
+
elif(self.dbType == "JDBC"):
|
|
1198
|
+
return self.jdbcSetTransactionIsolation(lvl)
|
|
1199
|
+
|
|
1200
|
+
def jdbcGetTransactionIsolation(self):
|
|
1201
|
+
r = self.connHandle.jconn.getTransactionIsolation()
|
|
1202
|
+
return r
|
|
1203
|
+
|
|
1204
|
+
def jdbcSetTransactionIsolation(self, lvl):
|
|
1205
|
+
r = self.connHandle.jconn.setTransactionIsolation(lvl)
|
|
1206
|
+
return r
|
|
1207
|
+
|
|
997
1208
|
def commit(self):
|
|
998
1209
|
if(self.dbType == "MYSQL"):
|
|
999
1210
|
self.connHandle.commit()
|
|
@@ -1045,11 +1256,11 @@ if __name__ == '__main__':
|
|
|
1045
1256
|
running_test = getInput("Run MySQL Test? ")
|
|
1046
1257
|
if running_test.lower() not in ('n','no'):
|
|
1047
1258
|
odb = dbtest()
|
|
1048
|
-
|
|
1259
|
+
|
|
1049
1260
|
print('\n')
|
|
1050
1261
|
|
|
1051
1262
|
if not odb:
|
|
1052
|
-
print( "Type run_test() to interactively test db connection")
|
|
1263
|
+
print( "Type run_test() to interactively test db connection")
|
|
1053
1264
|
else:
|
|
1054
1265
|
sqls, rset = sqltest( odb )
|
|
1055
1266
|
print( "\n - autoreconnect is True by default for MySQL, so if a connection socket error occurs (MySQL tested), it should auto reconnect" )
|
|
@@ -1077,17 +1288,17 @@ if __name__ == '__main__':
|
|
|
1077
1288
|
print( "now odb.reconnect_attempts = {0}".format(odb.reconnect_attempts) )
|
|
1078
1289
|
print( "setting odb.msgObj.message = ''" )
|
|
1079
1290
|
odb.msgObj.message = ''
|
|
1080
|
-
|
|
1291
|
+
|
|
1081
1292
|
print( "rerunning {s}".format(s=sqls) )
|
|
1082
|
-
|
|
1293
|
+
|
|
1083
1294
|
try:
|
|
1084
1295
|
sqls, rset = sqltest( odb, sqls )
|
|
1085
1296
|
except Exception as e:
|
|
1086
1297
|
print( "\nException in dbobj: {e}\n".format(e=e) )
|
|
1087
|
-
|
|
1298
|
+
|
|
1088
1299
|
print( "setting odb.autoreconnect back to True")
|
|
1089
1300
|
odb.autoreconnect = True
|
|
1090
1301
|
return odb
|
|
1091
1302
|
|
|
1092
|
-
# odb will be the interactively instantiated dbObj connection
|
|
1093
|
-
odb = run_test()
|
|
1303
|
+
# odb will be the interactively instantiated dbObj connection
|
|
1304
|
+
odb = run_test()
|
|
File without changes
|