import sshtunnel
import time
import logging
import mysql.connector
class SelectCommand():
def __init__(self,dbcmd,value = None, mul = False):
self.dbcmd = dbcmd
self.value = value
self.mul = mul
def execute(self):
try:
print("try1")
connection = mysql.connector.connect(
user='**myuser**', password='**pass**',
host='127.0.0.1', port=server.local_bind_port,
database='**myuser$test**', autocommit = True
)
print("try2")
connection.autocommit = True
mycursor = connection.cursor()
sql = self.dbcmd
val = self.value
mycursor.execute(sql, val)
myresult = mycursor.fetchone()
mycursor.close()
connection.close()
if myresult == None or self.mul == True:
return myresult
return myresult[0]
except Exception as e:
print(e)
return "server disconnect "
sshtunnel.SSH_TIMEOUT = 5.0
sshtunnel.TUNNEL_TIMEOUT = 5.0
def get_server():
#sshtunnel.DEFAULT_LOGLEVEL = logging.DEBUG
server = sshtunnel.SSHTunnelForwarder(
('ssh.pythonanywhere.com'),
ssh_username='**myuser**', ssh_password='**mypass**',
remote_bind_address=('**myuser.mysql.pythonanywhere-services.com**', 3306))
return server
server = get_server()
server.start()
while True :
if(server.is_active):
print("alive... " + (time.ctime()))
print(SelectCommand("SELECT * FROM A_table WHERE id = %s", (1,), mul = True).execute())
else:
print("reconnecting... " + time.ctime())
server.stop()
server = get_server()
server.start()
time.sleep(8)
Now i want use sshtunnel connect with database of pythonanywhere, and i want check connecting of sshtunnel if connect do select command else wait for new connecting. i try do Python: Automatically reconnect ssh tunnel after remote server gone down . but my problem is when i query database i try turn off my WIFI
my console show this message (Could not establish connection from ('127.0.0.1', 54466) to remote side of the tunnel) and Socket exception: An existing connection was forcibly closed by the remote host (10054) then it's result to stopping of my program. How can i fix.
Related
I currently have a long running python script (multiple days), which occasionally executes queries in a mysql db. The queries are executed from different threads.
I connect to the db as following:
import mysql.connector
import time
class DB():
connection = None
def __init__(self, host, user, password, database):
self.host = host;
self.user = user;
self.password = password;
self.database = database;
self.connect()
def connect(self):
try:
self.connection = mysql.connector.connect(
host = self.host,
user = self.user,
password = self.password,
database = self.database,
autocommit = True,
)
except Exception as exception:
print("[DBCONNECTION] {exception} Retrying in 5 seconds.".format(exception = str(exception)))
time.sleep(5)
self.connect()
db = DB("11.111.11.111", "mydb", "mydb", "mydb")
One of the functions to execute a query:
def getUsersDB(self):
db.connection.ping(reconnect=True)
cursor = db.connection.cursor()
cursor.execute("SELECT * FROM Users")
users = cursor.fetchall()
return users
I believe, that I'm far away from a good practice how I handle the connection. What is the correct way for such a case?
The problem with your approach is that db.connection.ping(reconnect=True) doesn't promise you a live connection.
You can read the function's description here:
https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlconnection-ping.html
You can try to use this:
class DB:
connection = None
def __init__(
self,
host: str,
user: str,
password: str,
database: str
) -> None:
self.host = host
self.user = user
self.password = password
self.database = database
self.connection = self.init_conn()
def init_conn(
self,
):
return mysql.connector.connect(
host=self.host,
user=self.user,
password=self.password,
database=self.database,
)
def get_cursor(
self,
):
# This will try to reconnect also.
# In case it fails, you will have to create a new connection
try:
self.connection.ping(
reconnect=True,
attempts=3,
delay=5,
)
except mysql.connector.InterfaceError as err:
self.connection = self.init_conn()
return self.connection.cursor()
And use the DB object like this:
def getUsersDB(self):
cursor = db.get_cursor() # cursor from a live connection
cursor.execute("SELECT * FROM Users")
users = cursor.fetchall()
return users
Using Python, how might I validate that SSH connection is successful after the following:
server = SSHTunnelForwarder(
(host_or_ip, 22),
ssh_username = "ssh_username",
ssh_private_key = path_to_key,
remote_bind_address = (another_host_or_ip, 5432)
)
server.start()
I use this to see if tunnel is open:
server.skip_tunnel_checkup = False
server.start()
server.check_tunnels()
print(server.tunnel_is_up, flush=True)
And in the log you will see :
{('0.0.0.0', 44004): True} # this tunnel is up
{('0.0.0.0', 44004): False} # this tunnel is not up
You can do that using a try-exceptblock.
ssh_address_or_host = ...
ssh_username = ...
ssh_password = ...
remote_bind_address = ...
try:
with SSHTunnelForwarder(
ssh_address_or_host = ssh_address_or_host,
ssh_username = ssh_username,
ssh_password = ssh_password,
remote_bind_address = remote_bind_address
) as server:
print("connected")
except Exception as e:
print("Non connected because: " + e)
I am newbie in python, so, it looks like my first project on that lang.
Everytime when I'm trying to run my script - I get different answers from mysql server.
The most frequent answer is OperationalError: (2006, 'MySQL server has gone away')
Sometimes I get output Thread: 11 commited (see code below).
And sometimes emergency stop (traslated, I have russian output in console).
Whatever if output full of commited - records in table still the same.
import MySQLdb
import pyping
import socket, struct
from threading import Thread
def ip2int(addr):
"""Convert ip to integer"""
return struct.unpack("!I", socket.inet_aton(addr))[0]
def int2ip(addr):
"""Convert integer to ip"""
return socket.inet_ntoa(struct.pack("!I", addr))
def ping(ip):
"""Pinging client"""
request = pyping.ping(ip, timeout=100, count=1)
return int(request.max_rtt)
class UpdateThread(Thread):
def __init__(self, records, name):
Thread.__init__(self)
self.database = MySQLdb.connect(host="***", port=3306, user="root", passwd="***", db="dns")
self.cursor = database.cursor()
self.name = name
self.records = records
def run(self):
print(self.name)
for r in self.records:
#latency = ping(int2ip(r[1])) what the hell :x
#ip = str(int2ip(r[1]))
id = str(r[0])
self.cursor.execute("""update clients set has_subn=%s where id=%s""" % (id, id))
self.database.commit()
print(self.name + " commited")
#start
database = MySQLdb.connect(host="***", port=3306, user="root", passwd="***", db="dns")
cursor = database.cursor()
cursor.execute("""select * from clients""")
data = cursor.fetchall() #All records from DataBase
count = len(data)
threads_counter = 10 #We are creating 10 threads for all records
th_count = count / threads_counter #Count of records for each thread
last_thread = count % threads_counter #Last records
threads = []
i = 0
while i < (count - last_thread):
temp_list = data[i:(i+th_count)]
#print(temp_list)
threads.append(UpdateThread(records = temp_list, name = "Thread: " + str((i/3) + 1)).start())
i += th_count
threads.append(UpdateThread(records = data[i: count], name = "Thread: 11").start())
P.S.
Another answers I found here is not helping me.
UPD:
I found that some(everytime another) thread print
OperationalError: (2013, 'Lost connection to MySQL server during query') and all next threads print OperationalError: (2013, 'Lost connection to MySQL server during query')
You need to close your DB connections when you're done with them or else the DB server will become overwhelmed and make your connections expire. For your program, I would change your code so that you have only one DB connection. You can pass a reference to it to your UpdateThread instances and close it when you're done.
database.close()
I can't connect remote server MySQL using Python.
first.py
#!/usr/bin/python
import MySQLdb
import second
DBHostname = second.hostname
DBuser = second.user
DBPWD = second.passwd
DB = second.db
dbcon = MySQLdb.connect(host=DBHostname,user=DBuser,passwd=DBPWD,db=DB)
dbcur = dbcon.cursor()
try:
dbcur.execute("select * from push_time where userid = %s", (e100075))
data = dbcur.fetchall() #Fetch all of the rows from query
for row in data : #Get Data's
wait_time = row[2]
print wait_time
dbcon.commit()
except:
dbcon.close()
second.py
#!/usr/bin/python
hostname = "192.12XX.XXX.XXX"
user = "user"
passwd = "password"
db = "dbname"
After running this program, I got the following error:
_mysql_exceptions.OperationalError: (2005, "Unknown MySQL server host '192.XXXX.XXX.XXX' (2)")
What am I doing wrong?
I'm trying use Python and pyodbc to access SQL server 2008. The first connection works. Then, after the program finishes its job, it closes the connection. When the program tries to access the database and connect to it again, it fails in the statement:
self.conn = pyodbc.connect(DRIVER=self.DRIVER, SERVER=self.SERVER, DATABASE=self.DATABASE, UID=self.UID, PWD=self.PWD, charset="UTF-8")
but the first time is OK. So does anyone know why? Below is the Python code:
class ODBC_MS:
def __init__(self, DRIVER,SERVER, DATABASE, UID, PWD):
''' initialization '''
self.DRIVER = DRIVER
self.SERVER = SERVER
self.DATABASE = DATABASE
self.UID = UID
self.PWD = PWD
def _GetConnect(self):
''' Connect to the DB '''
if not self.DATABASE:
raise(NameError,"no getting db name")
try:
self.conn = pyodbc.connect(DRIVER=self.DRIVER, SERVER=self.SERVER,
DATABASE=self.DATABASE, UID=self.UID,
PWD=self.PWD, charset="UTF-8")
except Exception,e:
print e.message
else:
self.cur = self.conn.cursor()
if not self.cur:
raise(NameError,"connected failed!")
else:
return self.cur, self.conn
def ExecNoQuery(self,conn, cursor, sql):
cursor.execute(sql)
ret = conn.commit()
return ret
def _UnConnect(self,conn, cursor):
conn.close()
if __name__ == '__main__':
ms = ODBC_MS('{SQL SERVER}', r'<server>', '<db>', '<user>', '<password>')
cursor, conn = ms._GetConnect() #connection
sql = "create table XX for example"
ret = ms.ExecNoQuery(conn, cursor,sql) #sql operation
ms._UnConnect(conn, cursor) #close db
#access the database the second time.
ms = ODBC_MS('{SQL SERVER}', r'<server>', '<db>', '<user>', '<password>')
cursor, conn = ms._GetConnect() # not success, I don't know why
sql = "create table XX for example"
ret = ms.ExecNoQuery(conn, cursor,sql) #sql operation
ms._UnConnect(conn, cursor) #close db
The second time when the program calls ms.GetConnect(), the statement self.conn = pyodbc.connect(DRIVER=self.DRIVER, SERVER=self.SERVER, DATABASE=self.DATABASE, UID=self.UID, PWD=self.PWD, charset="UTF-8") fails.