Inserting cipher text into mysql using python - mysql

So i have a program which will encrypt a string using AES and generate cipher which in bytes[].
I wish to store this cipher as it is in mysql database.
I found we could use VARBINARY data type in mysql to do so.
In what ways we could achieve so.
Here is my try to do so :
import ast
import mysql.connector
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
def encrypt(key, msg):
iv = get_random_bytes(16)
cipher = AES.new(key, AES.MODE_CFB, iv)
ciphertext = cipher.encrypt(msg) # Use the right method here
db = iv + ciphertext
print(db)
cursor.executemany(sql_para_query,db)
print(cursor.fetchone())
connection.commit()
return iv + ciphertext
def decrypt(key, ciphertext):
iv = ciphertext[:16]
ciphertext = ciphertext[16:]
cipher = AES.new(key, AES.MODE_CFB, iv)
msg = cipher.decrypt(ciphertext)
return msg.decode("utf-8")
if __name__ == "__main__":
connection = mysql.connector.connect(host = "localhost", database = "test_db", user = "sann", password = "userpass",use_pure=True)
cursor = connection.cursor(prepared = True)
sql_para_query = """insert into test1 values(UNHEX(%s)) """
ed = input("(e)ncrypt or (d)ecrypt: ")
key = str(1234567899876543)
if ed == "e":
msg = input("message: ")
s= encrypt(key, msg)
print("Encrypted message: ", s)
file = open("e_tmp","wb+")
file.write(s)
print(type(s))
elif ed == "d":
#smsg = input("encrypted message: ")
#file = open("e_tmp","rb")
#smsg = file.read()
#print(type(smsg))
sql_para_query = """select * from test1"""
cursor.execute(sql_para_query)
row = cursor.fetchone()
print(row)
#smsg = str(smsg)
#msg = ast.literal_eval(smsg)
#print(msg)
#print(type(msg))
#s=decrypt(key, msg)
#print("Decrypted message: ", s)
#print(type(s))
Error I'm getting :
Traceback (most recent call last): File
"/home/mr_pool/.local/lib/python3.6/site-packages/mysql/connector/cursor.py",
line 1233, in executemany
self.execute(operation, params) File "/home/mr_pool/.local/lib/python3.6/site-packages/mysql/connector/cursor.py",
line 1207, in execute
elif len(self._prepared['parameters']) != len(params): TypeError: object of type 'int' has no len()
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File "tmp1.py", line 36, in
s= encrypt(key, msg) File "tmp1.py", line 14, in encrypt
cursor.executemany(sql_para_query,db) File "/home/mr_pool/.local/lib/python3.6/site-packages/mysql/connector/cursor.py",
line 1239, in executemany
"Failed executing the operation; {error}".format(error=err)) mysql.connector.errors.InterfaceError: Failed executing the operation;
object of type 'int' has no len()
Any other alternatives are also welcome.
My ultimate goal is to store the encrypted text in database.

I reproduced your error, but it seems there are more errors in your code.
The key as well as the message are strings, therefore I got this error:
TypeError: Object type <class 'str'> cannot be passed to C code
Which I fixed by encoding them in utf-8:
# line 38:
key = str(1234567899876543).encode("utf8")
# .... line 41:
s= encrypt(key, msg.encode("utf8"))
The UNHEX function in your SQL Query is not needed because we are entering the data as VARBINARY. You can change your statement to:
"""insert into test1 values(%s) """
The function executemany() can be replaced by execute() because you are only entering one statement. However I will write the solution for using both, execute or executemany.
insert with execute():
From the documentation:
cursor.execute(operation, params=None, multi=False)
iterator = cursor.execute(operation, params=None, multi=True)
This method executes the given database operation (query or command). The parameters found in the tuple or dictionary params are bound to the variables in the operation. Specify variables using %s or %(name)s parameter style (that is, using format or pyformat style). execute() returns an iterator if multi is True.
https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html
So we need just to build a tuple with your parameters by changing the cursor.execute line to:
cursor.execute(sql_para_query, (db, ))
insert with executemany():
From the documentation:
cursor.executemany(operation, seq_of_params)
This method prepares a database operation (query or command) and executes it against all parameter sequences or mappings found in the sequence seq_of_params.
https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-executemany.html
Therefore we need to build a sequence with values you'd like to insert. In your case just one value:
cursor.executemany(sql_para_query, [(db, )])
To insert multiple values, you can add as many tuples into your sequence as you want.
full code:
import ast
import mysql.connector
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
def encrypt(key, msg):
iv = get_random_bytes(16)
cipher = AES.new(key, AES.MODE_CFB, iv)
ciphertext = cipher.encrypt(msg) # Use the right method here
db = iv + ciphertext
cursor.execute(sql_para_query, (db, ))
connection.commit()
return iv + ciphertext
def decrypt(key, ciphertext):
iv = ciphertext[:16]
ciphertext = ciphertext[16:]
cipher = AES.new(key, AES.MODE_CFB, iv)
msg = cipher.decrypt(ciphertext)
return msg.decode("utf-8")
if __name__ == "__main__":
connection = mysql.connector.connect(host = "localhost", database = "test_db", user = "sann", password = "userpass",use_pure=True)
cursor = connection.cursor(prepared = True)
sql_para_query = """insert into test1 values(%s) """
ed = input("(e)ncrypt or (d)ecrypt: ")
key = str(1234567899876543).encode("utf8")
if ed == "e":
msg = input("message: ")
s= encrypt(key, msg.encode("utf8"))
print("Encrypted message: ", s)
file = open("e_tmp","wb+")
file.write(s)
print(type(s))
elif ed == "d":
sql_para_query = """select * from test1"""
cursor.execute(sql_para_query)
row = cursor.fetchone()
msg = row[0] # row is a tuple, therefore get first element of it
print("Unencrypted message: ", msg)
s=decrypt(key, msg)
print("Decrypted message: ", s)
output:
#encrypt:
(e)ncrypt or (d)ecrypt: e
message: this is my test message !!
Encrypted message: b"\x8f\xdd\xe6f\xb1\x8e\xb51\xc1'\x9d\xbf\xb5\xe1\xc7\x87\x99\x0e\xd4\xb2\x06;g\x85\xc4\xc1\xd2\x07\xb5\xc53x\xb9\xbc\x03+\xa2\x95\r4\xd1*"
<class 'bytes'>
#decrypt:
(e)ncrypt or (d)ecrypt: d
Unencrypted message: bytearray(b"\x8f\xdd\xe6f\xb1\x8e\xb51\xc1\'\x9d\xbf\xb5\xe1\xc7\x87\x99\x0e\xd4\xb2\x06;g\x85\xc4\xc1\xd2\x07\xb5\xc53x\xb9\xbc\x03+\xa2\x95\r4\xd1*")
Decrypted message: this is my test message !!

Related

python 3 : deserialize nested dictionaries from sqlite

I have this sqlite3.register_converter function :
def str_to_dict(s: ByteString) -> Dict:
if s and isinstance(s, ByteString):
s = s.decode('UTF-8').replace("'", '"')
return json.loads(s)
raise TypeError(f'value : "{s}" should be a byte string')
which returns this exception text :
File "/usr/lib64/python3.7/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 30 (char 29)
when encounter with this string :
s = b"{'foo': {'bar': [('for', 'grid')]}}"
It seems that the issue comes from the nested list/tuple/dictionary but what I don't understand is that in the sqlite shell, the value is correctly returned with a select command :
select * from table;
whereas the same command issued from a python script returned the exception above :
class SqliteDb:
def __init__(self, file_path: str = '/tmp/database.db'):
self.file_path = file_path
self._db = sqlite3.connect(self.file_path, detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
if self._db:
self._cursor = self._db.cursor()
else:
raise ValueError
# register data types converters and adapters
sqlite3.register_adapter(Dict, dict_to_str)
sqlite3.register_converter('Dict', str_to_dict)
sqlite3.register_adapter(List, list_to_str)
sqlite3.register_converter('List', str_to_list)
def __del__(self):
self._cursor.close()
self._db.close()
def select_from(self, table_name: str):
with self._db:
query = f'SELECT * FROM {table_name}'
self._cursor.execute(query)
if __name__ == '__main__':
try:
sq = SqliteDb()
selection_item = sq.select_from("table")[0]
print(f'selection_item : {selection_item}')
except KeyboardInterrupt:
print('\n')
sys.exit(0)
s, the value is already saved in database with no issue. Only the selection causes this issue.
So, anybody has a clue why ?
Your input is really a Python dict literal, and contains structures such as the tuple ('for', 'grid') that cannot be directly parsed as JSON even after you replace single quotes with double quotes.
You can use ast.literal_eval instead to parse the input:
from ast import literal_eval
def str_to_dict(s: ByteString) -> Dict:
return literal_eval(s.decode())

Incorrect number of parameters in prepared statement

I'm having a heck of a time getting the mysql.connector module to work. I'd really like to find some accurate documentation on it. By hit and by miss, I have arrived here.
Traceback (most recent call last):
File "update_civicrm_address.py", line 80, in <module>
cursor.execute(mysql_select_query, address_id)
File "/home/ubuntu/.local/lib/python3.6/site-packages/mysql/connector/cursor.py", line 1210, in execute
msg="Incorrect number of arguments " \
mysql.connector.errors.ProgrammingError: 1210: Incorrect number of arguments executing prepared statement
Here is the program (it's a bit messy because I have tried so many things to get it to work). Aside from the fact that the update is not working at all, what is causing the error? There is only one parameter and it is accounted for.
import sys
import mysql.connector
import csv
import os
from mysql.connector import Error
from mysql.connector import errorcode
#Specify the import file
try:
inputCSV = 'geocoded_rhode_island_export.csv'
#Open the file and give it a handle
csvFile = open(inputCSV, 'r')
#Create a reader object for the input file
reader = csv.reader(csvFile, delimiter = ',')
except IOError as e:
print("The input file ", inputCSV, " was not found", e)
exit()
try:
conn = mysql.connector.connect(host='localhost',
database='wordpress',
user='wp_user',
password='secret!',
use_pure=True)
cursor = conn.cursor(prepared=True)
except mysql.connector.Error as error:
print( "Failed to connect to database: {}".format(error))
exit()
try:
record_count = 0
for row in reader:
contact_id,address_id,last_name, first_name, middle_name, longitude, latitude = row
print(row)
#Update single record now
print(address_id)
cursor.execute(
"""
update civicrm_address
set
geo_code_1 = %s,
geo_code_2 = %s
where
id = %s
and
location_type_id = %s
""",
(longitude, latitude, address_id, 6)
)
conn.commit
print(cursor.rowcount)
print("Record updated successfully")
mysql_select_query = """
select
id,
geo_code_1,
geo_code_2
from
civicrm_address
where
id = %s
"""
input = (address_id)
cursor.execute(mysql_select_query, address_id)
record = cursor.fetchone()
print(record)
record_count = record_count + 1
finally:
print(record_count, " records updated")
#closing database connection.
if(conn.is_connected()):
conn.close()
print("connection is closed")
The is an error in the code
conn.commit
should be
conn.commit()

how to handle value errors in while 1 loop with scheduling it with a Timer class

i have written a code to read registers of a modbus communication protocol. i have attached the code below as well.. am able to overcome the i/o errors by exception handling method where as the value error that i get , am not able throw that error and move on.
Basically what i am doing is am reading the data in the registers and sending up to the server. but my requirement is i have to read the values every second and for 24 hours. so i need to build a robust system that will overcome these value errors and continue executing the threads i have created.
the code to read registers is given below :
import minimalmodbus
import serial
from ctypes import *
import struct
import time
minimalmodbus.BAUDRATE = 9600
minimalmodbus.PARITY = serial.PARITY_NONE
minimalmodbus.BYTESIZE = 8
minimalmodbus.TIMEOUT=5
minimalmodbus.CLOSE_PORT_AFTER_EACH_CALL = True
energy_meter = serial.Serial("/dev/ttyUSB0", baudrate=9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=5)
energy_meter = minimalmodbus.Instrument('/dev/ttyUSB0', 2, mode='rtu')
#energy_meter.debug = True
def convert_in_float(value1, value2):
raw = struct.pack('>HH',value1,value2)
ans = struct.unpack('>f', raw)[0]
return ans
def sdm630():
parameter_list1 = [ 0 ] * 0x12
parameter_list2 = [ 0 ] * 3
parameter_list3 = [ 0 ] * 6
#print energy_meter
error = 0
try:
index = 0
read_values1 = energy_meter.read_registers( 0 , 0x24, 4)
for i in range ( 0, 0x24, 2):
parameter_list1[index] = convert_in_float( read_values1[i], read_values1[i+1])
#print "Parameter read from register : ", hex(index), "is : ", parameter_list1[index] ,"\n"
index = index + 1
#read parameter list 2 & 3 in a similar way
error = 0
return error, parameter_list1, parameter_list2, parameter_list3, int(time.time())
except IOError or ValueError:
print "got error"
error = 1
return error, parameter_list1, parameter_list2, parameter_list3, int(time.time())
also, i have written a separate code to dump all data to server and is shown below :
import time
from pymongo import MongoClient
client = MongoClient('mongodb://10.32.36.40:27017')
db = client.clytics
collection = db['raspberry_pi']
def pushData(error, value1, value2, value3, value4):
if error == 0 :
temp_js = {
#variable assignment
}
temp_js_id = collection.insert(temp_js)
using the above two codes i have created threads for each function. and i only execute this code and after 20 minutes of execution , i get value errors and the program doesnt execute anymore. the main program is given below :
import time
from threading import Thread
from threading import Timer
from Queue import Queue
from modbus import sdm630
from dumpInDB import pushData
from processData import process_the_data
DELAY_SEC = 1
DELAY_MIN = 60
LOOP_LIMIT = 60
def getData(q):
error, parameter_list1, parameter_list2 , parameter_list3, parameter_list4= sdm630()
print "In getData - data:", parameter_list1, parameter_list2
q.put([error, parameter_list1, parameter_list2, parameter_list3, parameter_list4])
def processData(q1,q2):
sec_data = q1.get()
min_data = process_the_data(sec_data)
print "In processData - data:", sec_data, min_data
q2.put(min_data)
print "queue:", q2.qsize()
def putData(q):
#print "In putData - data:", value[0], value[1], value[2]
for i in range(0, q.qsize()):
value = q.get()
print "In putData - data:", value[0], value[1], value[2], value[3]
pushData( value[0], value[1] , value[2], value[3] , value[4])
def thread1(threadName, q):
i = 0
while 1:
t = Timer( DELAY_SEC, getData, args = (q,))
t.start()
time.sleep(DELAY_SEC)
def thread2( threadName, q1,q2):
i = 0
print "in thread2"
while 1:
t = Timer( DELAY_SEC, processData, args = (q1,q2,))
t.start()
time.sleep(DELAY_SEC)
def thread3( threadName, q):
i = 0
print "in thread3"
while 1:
t = Timer( DELAY_MIN, putData, args = (q,))
t.start()
print "schedule time - min"
time.sleep(DELAY_MIN)
queue_second = Queue()
queue_minute = Queue()
thread1 = Thread( target=thread1, args=("Thread-1", queue_second) )
thread2 = Thread( target=thread2, args=("Thread-2", queue_second, queue_minute) )
thread3 = Thread( target=thread3, args=("Thread-3", queue_minute) )
thread1.start()
thread2.start()
thread3.start()
thread1.join()
thread2.join()
thread3.join()
am stuck with this error. shown below :
minimalmodbus.Instrument<id=0xb6b2d9b8, address=2, mode=rtu, close_port_after_each_call=True, precalculate_read_size=True, debug=False, serial=Serial<id=0xb6b482f0, open=False>(port='/dev/ttyUSB0', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=5, xonxoff=False, rtscts=False, dsrdtr=False)>
Traceback (most recent call last):
File "topScript.py", line 7, in <module>
from modbus import sdm630
File "/home/pi/scripts/modbus.py", line 60, in <module>
sdm630()
File "/home/pi/scripts/modbus.py", line 32, in sdm630
read_values1 = energy_meter.read_registers( 0 , 0x24, 4)
File "/usr/local/lib/python2.7/dist-packages/minimalmodbus.py", line 498, in read_registers
numberOfRegisters=numberOfRegisters, payloadformat='registers')
File "/usr/local/lib/python2.7/dist-packages/minimalmodbus.py", line 697, in _genericCommand
payloadFromSlave = self._performCommand(functioncode, payloadToSlave)
File "/usr/local/lib/python2.7/dist-packages/minimalmodbus.py", line 798, in _performCommand
payloadFromSlave = _extractPayload(response, self.address, self.mode, functioncode)
File "/usr/local/lib/python2.7/dist-packages/minimalmodbus.py", line 1075, in _extractPayload
raise ValueError(text)
ValueError: Checksum error in rtu mode: '\xa6\xe6' instead of '\xf7[' . The response is: '\xff\xf7HCeN\xce\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x80\x00\x00?\x80\x00\x00?\x80\x00\x00\xa6\xe6' (plain response: '\xff\xf7HCeN\xce\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
sometimes value error keeps popping up for sometime and finally fails and gives a message saying no more threads can be created.(reached to maximum level)
Your syntax to handle multiple exceptions is wrong. Use something like:
except (ValueError, IOError):
For more details see the Python tutorial https://docs.python.org/2/tutorial/errors.html

Reading binary .SAVE files?

I was wondering how to open or read a binary file that has been saved in octave, with the extension .SAVE? I have tried opening it with MATLAB, using the 'load' function in octave, but nothing seems to be working. I'm trying to understand someone else's code and they have saved the output of a simulation in this file.
The Octave binary format is briefly described in the comments before the function read_binary_data() in load-save.cc.
Are you sure the file is in "Octave binary format". The file ending ".SAVE" can be choosen arbitrary so this could also be CSV, gzipped...
You can run "file yourfile.SAFE" and paste the output or check the first bytes of your file if they are "Octave-1-L" or "Octave-1-B".
If you want to use these files from another program than GNU Octave I would suggest loading it in Octave and safe it in an other format. See "help save" for a list of supported formats.
EDIT:
Because the initial poster asked: Of course you can use GNU Octave from the terminal (no need for the GUI and I don't now to which software part you refer when you are using the phrase "octave GUI", see here Octave FAQ). Just install it for your used platform install instructions on wiki.octave.org and run it.
Code for reading octave binary save files in python 2/3.
Tested on:
strings
single and double precision real and complex floats
various integer types
scalar, matrix and array
Unsupported:
struct
cell array
...
Python code:
# This code is public domain
from __future__ import print_function
import sys
from collections import OrderedDict
import numpy as np
if sys.version_info[0] > 2:
def tostr(s):
return s.decode('utf8')
def decode(s, encoding='utf8'):
return s.decode(encoding)
STR_ENCODING = 'utf8'
else:
def tostr(s):
return s
def decode(s, encoding='utf8'):
return unicode(s, encoding)
STR_ENCODING = None
DATA_TYPES = {
1: "scalar",
2: "matrix",
3: "complex scalar",
4: "complex matrix",
5: "old_string",
6: "range",
7: "string",
}
TYPE_CODES = {
0: "u1",
1: "u2",
2: "u4",
3: "i1",
4: "i2",
5: "i4",
6: "f4",
7: "f8",
8: "u8",
9: "i8",
}
DTYPES = {k: np.dtype(v) for k, v in TYPE_CODES.items()}
def loadoct(fd, encoding=STR_ENCODING):
"""
Read an octave binary file from the file handle fd, returning
an array of structures. If encoding is not None then convert
strings from bytes to unicode. Default is STR_ENCODING, which
is utf8 for python 3 and None for python 2, yielding arrays
of type str in each dialect.
"""
magic = fd.read(10)
assert(magic == b"Octave-1-L" or magic == b"Octave-1-B")
endian = "<" if magic[-1:] == b"L" else ">"
# Float type is 0: IEEE-LE, 1: IEEE-BE, 2: VAX-D, 3: VAX-G, 4: Cray
# Not used since Octave assumes IEEE format floats.
_float_format = fd.read(1)
len_dtype = np.dtype(endian + "i4")
def read_len():
len_bytes = fd.read(4)
if not len_bytes:
return None
return np.frombuffer(len_bytes, len_dtype)[0]
table = OrderedDict()
while True:
name_length = read_len()
if name_length is None: # EOF
break
name = tostr(fd.read(name_length))
doc_length = read_len()
doc = tostr(fd.read(doc_length)) if doc_length else ''
is_global = bool(ord(fd.read(1)))
data_type = ord(fd.read(1))
if data_type == 255:
type_str = tostr(fd.read(read_len()))
else:
type_str = DATA_TYPES[data_type]
#print("reading", name, type_str)
if type_str.endswith("scalar"):
if type_str == "scalar":
dtype = DTYPES[ord(fd.read(1))]
elif type_str == "complex scalar":
_ = fd.read(1)
dtype = np.dtype('complex128')
elif type_str == "float complex scalar":
_ = fd.read(1)
dtype = np.dtype('complex64')
else:
dtype = np.dtype(type_str[:-7])
dtype = dtype.newbyteorder(endian)
data = np.frombuffer(fd.read(dtype.itemsize), dtype)
table[name] = data[0]
elif type_str.endswith("matrix"):
ndims = read_len()
if ndims < 0:
ndims = -ndims
dims = np.frombuffer(fd.read(4*ndims), len_dtype)
else:
dims = (ndims, read_len())
count = np.prod(dims)
if type_str == "matrix":
dtype = DTYPES[ord(fd.read(1))]
elif type_str == "complex matrix":
_ = fd.read(1)
dtype = np.dtype('complex128')
elif type_str == "float complex matrix":
_ = fd.read(1)
dtype = np.dtype('complex64')
else:
dtype = np.dtype(type_str[:-7])
dtype = dtype.newbyteorder(endian)
data = np.frombuffer(fd.read(count*dtype.itemsize), dtype)
# Note: Use data.copy() to make a modifiable array.
table[name] = data.reshape(dims, order='F')
elif type_str == "old_string":
data = fd.read(read_len())
if encoding is not None:
data = decode(data, encoding)
table[name] = data
elif type_str in ("string", "sq_string"):
nrows = read_len()
if nrows < 0:
ndims = -nrows
dims = np.frombuffer(fd.read(4*ndims), len_dtype)
count = np.prod(dims)
fortran_order = np.frombuffer(fd.read(count), dtype='uint8')
c_order = np.ascontiguousarray(fortran_order.reshape(dims, order='F'))
data = c_order.view(dtype='|S'+str(dims[-1]))
if encoding is not None:
data = np.array([decode(s, encoding) for s in data.flat])
table[name] = data.reshape(dims[:-1])
else:
data = [fd.read(read_len()) for _ in range(nrows)]
if encoding is not None:
data = [decode(s, encoding) for s in data]
table[name] = np.array(data)
else:
raise NotImplementedError("unknown octave type "+type_str)
#print("read %s:%s"%(name, type_str), table[name])
return table
def _dump(filename, encoding=STR_ENCODING):
import gzip
if filename.endswith('.gz'):
with gzip.open(filename, 'rb') as fd:
table = loadoct(fd, encoding)
else:
with open(filename, 'rb') as fd:
table = loadoct(fd, encoding)
for k, v in table.items():
print(k, v)
if __name__ == "__main__":
#_dump(sys.argv[1], encoding='utf8') # unicode
#_dump(sys.argv[1], encoding=None) # bytes
_dump(sys.argv[1]) # str, encoding=STR_ENCODING

Test connection to MySQL server

Whats the best / correct way to test a connection to a MySQL server.. can you for example ping it..? I'm using MySQLdb and python.
I want my program to be structured in the following way
....connect to MySQL server
database = MySQLdb.connect(host="127.0.0.1 etc...
While true:
**... Check to see if connection is still alive if not reconnect**
... send data to MySQL...
time.sleep(30)
This is what I have used.
import MySQLdb
try:
import MySQLdb.converters
except ImportError:
_connarg('conv')
def connect(host='ronak.local', user='my_dev_1', passwd='my_dev_1', db='my_dev1', port=3306):
try:
orig_conv = MySQLdb.converters.conversions
conv_iter = iter(orig_conv)
convert = dict(zip(conv_iter, [str,] * len(orig_conv.keys())))
print "Connecting host=%s user=%s db=%s port=%d" % (host, user, db, port)
conn = MySQLdb.connect(host, user, passwd, db, port, conv=convert)
except MySQLdb.Error, e:
print "Error connecting %d: %s" % (e.args[0], e.args[1])
return conn
def parse_data_and_description(cursor, data, rs_id):
res = []
cols = [d[0] for d in cursor.description]
for i in data:
res.append(OrderedDict(zip(cols, i)))
return res
rs_id=0;
def get_multiple_result_sets():
conn = connect()
cursor = conn.cursor( )
final_list = []
try:
conn.autocommit(True)
cursor.execute ("CALL %s%s" % (sp, args))
while True:
rs_id+=1
data = cursor.fetchall( )
listout = parse_data_and_description(cursor, data, rs_id)
print listout
if cursor.nextset( )==None:
# This means no more recordsets available
break
print "\n"
# Consolidate all the cursors in a single list
final_list.append(listout)
print final_list
except MySQLdb.Error, e:
# Lets rollback the transaction in case of an exception
conn.rollback()
print "Transaction aborted: %d: %s" % (e.args[0], e.args[1])
cursor.close( )
conn.close()
else:
# Commit the transaction in case of no failures/exceptions
conn.commit()
print "Transaction succeeded"
cursor.close( )
conn.close()