python mysql connection auto connect on error - python

I have a problem with my python mysql connection which I need help with.
My setup is two Pi's running servers on each one. One Pi (SolartPi) has Mysql database collecting data. The other pi (OfficePi) is connecting to the solarPi database to retrieve and update data over a network connection.
My main script works all ok until I have to reboot the SolarPi for a maintenance or power problem and the connection to the OfficePi is lost. The python script on the officePi then goes into a fault loop "2006, MYSQL Server has gone away" Below is a sample of this script.
import MySQLdb
connSolar = MySQLdb.connect("192.xxx.x.x", "external", "xxxxx", "xxxxx")
#eternal connection to solar pi database
cursSolar = connSolar.cursor()
while 1:
try:
cursSolar.execute("SELECT * FROM dashboard")
connSolar.commit()
for reading in cursSolar.fetchall():
heatingDemand = reading[2] #get heating demand from dB
print heatingDemand
except (MySQLdb.Error, MySQLdb.Warning) as e:
print (e)
connSolar.close()
So I tried rewriting this with the script from stackoverflow and a web site as shown below, but this now terminates the program when SolarPi is rebooted with the following error
_mysql_exceptions.OperationalError: (2003, 'Can\'t connect to MySQL server on \'192.xxx.x.x' (111 "Connection refused")')
import MySQLdb
class DB:
con = None
def connect(self):
self.conn = MySQLdb.connect("192.xxx.x.x", "xxxxx", "xxxxxx", "house") #eternal connection to solar pi database
def query(self, sql):
try:
cursor = self.conn.cursor()
cursor.execute(sql)
except (AttributeError, MySQLdb.OperationalError):
self.connect()
cursor = self.conn.cursor()
cursor.execute(sql)
return cursor
while 1:
db = DB()
sql = "SELECT * FROM dashboard"
cur = db.query(sql)
for reading in cur.fetchall():
heatingDemand = reading[2] #get heating demand from dB
print heatingDemand
Is there a way for the OfficePi to keep trying to connect to SolarPi mysql database when it has shut down.

Change your code to check a valid connection each loop otherwise pass:
import MySQLdb
class DB:
def connect(self):
try:
self.conn = MySQLdb.connect("192.xxx.x.x", "xxxxx", "xxxxxx", "house")
except (MySQLdb.Error, MySQLdb.Warning) as e:
print (e)
self.conn = None
return self.conn
def query(self, sql):
try:
cursor = self.conn.cursor()
cursor.execute(sql)
except (AttributeError, MySQLdb.OperationalError):
self.connect()
cursor = self.conn.cursor()
cursor.execute(sql)
return cursor
while 1:
db = DB()
conn = db.connect()
if conn:
sql = "SELECT * FROM dashboard"
cur = db.query(sql)
for reading in cur.fetchall():
heatingDemand = reading[2] #get heating demand from dB
print heatingDemand

Related

SQL Database file not showing up in folder?

I am trying to create a database file using the following code:
def dbconnect():
try:
sqliteConnection = sqlite3.connect('SQLite_Python.db')
cursor = sqliteConnection.cursor()
print("Database created and Successfully Connected to SQLite")
sqlite_select_Query = "select sqlite_version();"
cursor.execute(sqlite_select_Query)
record = cursor.fetchall()
print("SQLite Database Version is: ", record)
cursor.close()
except sqlite3.Error as error:
print("Error while connecting to sqlite", error)
finally:
if sqliteConnection:
sqliteConnection.close()
print("The SQLite connection is closed")
conn = dbconnect()
conn.close()
yet when I run the code, although there are no file errors, it doesnt print anything or create a SQL file in the folder of the python code.
I can't seem to figure out what is going wrong.

Accessing a remote database through SSH tunnel

I want to access a remote database through SSH tunnel.
server = SSHTunnelForwarder(
('172.17.9.125', 22),
ssh_password="123456",
ssh_username="root",
remote_bind_address=('127.0.0.1', 3306))
server.start()
database = pymysql.connect(host='127.0.0.1',
port=3306,
user='root',
passwd='root')
try:
dbsql = "CREATE DATABASE TestDB" # Create database
except Exception as e:
print("Error: ", e)
database.cursor().execute(dbsql)
global db, cursor
db = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='root', db='TestDB')
cursor = db.cursor()
print("Connected to MySQL database")
f = open("testdb.sql") # Execute .sql file, creating data tables
full_sql = f.read()
sql_commands = full_sql.split(';')[:-1]
try:
for sql_command in sql_commands:
if sql_command is not None:
cursor.execute(sql_command)
else:
print("Null")
print("Created database")
except Exception as e:
print("Error: ", e)
I want to create a new database named as "TESTDB" on this remote server, 172.17.9.125.
But I get this database created in localhost. What am I doing wrong here?
Since you already have a database running, your 3306 port is used in that so won't be able to bind.
Solution : bind it to some other port and try to connect to that.
You can bind to another address using local_bind_address=('0.0.0.0', 1234) (this will be your target local address/port to which it will be bound) in your arguments to SSHTunnelForwarder.
So your connection TunnelForwarder should be something like this
server = SSHTunnelForwarder(
('172.17.9.125', 22),
ssh_password="123456",
ssh_username="root",
local_bind_address=('0.0.0.0', 1234),
remote_bind_address=('127.0.0.1', 3306))
And now connection will be made to port 1234
database = pymysql.connect(host='127.0.0.1',
port=1234,
user='root',
passwd='root')
db = pymysql.connect(host='127.0.0.1', port=1234, user='root', passwd='root', db='TestDB')

How would one connect an SQL db securely to an external client?

I'm attempting to connect a database, located on a web server, to a robot but I do not know how to connect the database to the robot. I would like the robot to run SELECT and UPDATE queries from the robot. The other issue is that I do not intend on using C-languages or Java; I plan on using python in the main control system.
I do know:
PHP
VBScript
Batch
Python
If anyone knows how to connect the DB to a bot it would be a great help.
So basically how to connect to an SQL DB in python? I'm working on a virtual bot right now doing the same thing. Look into the module , SQL-connector! http://www.mysqltutorial.org/python-connecting-mysql-databases/
You would start with creating a config.ini with your credentials
[mysql]
host = localhost
database = python_mysql
user = root
password =
Read Config.ini and return a dictionary
from configparser import ConfigParser
def read_db_config(filename='config.ini', section='mysql'):
""" Read database configuration file and return a dictionary object
:param filename: name of the configuration file
:param section: section of database configuration
:return: a dictionary of database parameters
"""
# create parser and read ini configuration file
parser = ConfigParser()
parser.read(filename)
# get section, default to mysql
db = {}
if parser.has_section(section):
items = parser.items(section)
for item in items:
db[item[0]] = item[1]
else:
raise Exception('{0} not found in the {1} file'.format(section, filename))
return db
and connect to MYSQL database
from mysql.connector import MySQLConnection, Error
from python_mysql_dbconfig import read_db_config
def connect():
""" Connect to MySQL database """
db_config = read_db_config()
try:
print('Connecting to MySQL database...')
conn = MySQLConnection(**db_config)
if conn.is_connected():
print('connection established.')
else:
print('connection failed.')
except Error as error:
print(error)
finally:
conn.close()
print('Connection closed.')
if __name__ == '__main__':
connect()
and update statement would look like the following
def update_book(book_id, title):
# read database configuration
db_config = read_db_config()
# prepare query and data
query = """ UPDATE books
SET title = %s
WHERE id = %s """
data = (title, book_id)
try:
conn = MySQLConnection(**db_config)
# update book title
cursor = conn.cursor()
cursor.execute(query, data)
# accept the changes
conn.commit()
except Error as error:
print(error)
finally:
cursor.close()
conn.close()
if __name__ == '__main__':
update_book(37, 'The Giant on the Hill *** TEST ***')

connect to mysql in a loop

i have to connect to mysql server and grab some data for ever
so i have two way
1)connect to mysql the grab data in a while
conn = mysql.connector.connect(user='root',password='password',host='localhost',database='db',charset='utf8',autocommit=True)
cursor = conn.cursor(buffered=True)
while True:
cursor.execute("statments")
sqlData = cursor.fetchone()
print(sqlData)
sleep(0.5)
this working good but if script crashed due to mysql connection problem script goes down
2)connect to mysql in while
while True:
try:
conn = mysql.connector.connect(user='root',password='password',host='localhost',database='db',charset='utf8',autocommit=True)
cursor = conn.cursor(buffered=True)
cursor.execute("statments")
sqlData = cursor.fetchone()
print(sqlData)
cursor.close()
conn.close()
sleep(0.5)
except:
print("recoverable error..")
both code working good but my question is which is better?!
Among these two, better way will be to use a single connection but create a new cursor for each statement because creation of new connection takes time but creating a new cursor is fast. You may update the code as:
conn = mysql.connector.connect(user='root',password='password',host='localhost',database='db',charset='utf8',autocommit=True)
while True:
try:
cursor = conn.cursor(buffered=True)
cursor.execute("statments")
sqlData = cursor.fetchone()
print(sqlData)
except Exception: # Catch exception which will be raise in connection loss
conn = mysql.connector.connect(user='root',password='password',host='localhost',database='db',charset='utf8',autocommit=True)
cursor = conn.cursor(buffered=True)
finally:
cursor.close()
conn.close() # Close the connection
Also read Defining Clean-up Actions regarding the usage of try:finally block.

How to handle exception in the "finally" block?

Given the following Python code:
# Use impyla package to access Impala
from impala.dbapi import connect
import logging
def process():
conn = connect(host=host, port=port) # Mocking host and port
try:
cursor = conn.cursor()
# Execute query and fetch result
except:
loggin.error("Task failed with some exception")
finally:
cursor.close() # Exception here!
conn.close()
The connection to Impala was created. But there was an exception in cursor.close() due to Impala timeout.
What is the proper way to close the cursor and conn given the latent exception?
You have to nest the try-blocks:
def process():
conn = connect(host=host, port=port) # Mocking host and port
try:
cursor = conn.cursor()
try:
# Execute query and fetch result
finally:
# here cursor may fail
cursor.close()
except:
loggin.error("Task failed with some exception")
finally:
conn.close()
To avoid such try-finally-blocks, you can use the with-statement:
def process():
conn = connect(host=host, port=port) # Mocking host and port
try:
with conn.cursor() as cursor:
# Execute query and fetch result
# cursor is automatically closed
except:
loggin.error("Task failed with some exception")
finally:
conn.close()

Categories