Issues connecting to PythonAnywhere SQL Server - python

I'm trying to create a table in mySQL server running on pythonAnywhere from my local machine.
I followed the getting started guide, https://help.pythonanywhere.com/pages/AccessingMySQLFromOutsidePythonAnywhere, but I'm running into a OperationalError: (2013, 'Lost connection to MySQL server during query').
Here is my code:
import MySQLdb
import sshtunnel
sshtunnel.SSH_TIMEOUT = 10
sshtunnel.TUNNEL_TIMEOUT = 10
with sshtunnel.SSHTunnelForwarder(
('ssh.pythonanywhere.com'),
ssh_username='MyUSERNAME', ssh_password='***',
remote_bind_address=('MyUSERNAME.mysql.pythonanywhere-services.com', 3306)
) as tunnel:
connection = MySQLdb.connect(
user='MyUSERNAME',
passwd='***',
host='127.0.0.1', port=tunnel.local_bind_port,
db='MyUSERNAME$liveSports',
)
cur = connection.cursor()
with connection:
cur.execute("CREATE TABLE table_one (date TEXT, start_time TEXT)")
I'm not sure why I'm getting this error, or how to resolve it.
Similar errors, Lost connection to MySQL server during query , suggest that either I'm sending an incorrect query to my server, but as far as I know this is a valid query, or that my packet is too large, which I don't believe an empty table would be.
I'm new to SQL, but I can't seem to find an answer to this question.

You must leave the tunnel open. This is the easy way:
import MySQLdb
import sshtunnel
sshtunnel.SSH_TIMEOUT = 10
sshtunnel.TUNNEL_TIMEOUT = 10
tunnel = sshtunnel.SSHTunnelForwarder(
('ssh.pythonanywhere.com'),
ssh_username='MyUSERNAME', ssh_password='***',
remote_bind_address=('MyUSERNAME.mysql.pythonanywhere-services.com', 3306)
)
connection = MySQLdb.connect(
user='MyUSERNAME',
passwd='***',
host='127.0.0.1', port=tunnel.local_bind_port,
db='MyUSERNAME$liveSports',
)
cur = connection.cursor()
cur.execute("CREATE TABLE table_one (date TEXT, start_time TEXT)")
You could put all of your database stuff in a function and use
with sshtunnel.SSHTunnelForwarder(
('ssh.pythonanywhere.com'),
ssh_username='MyUSERNAME', ssh_password='***',
remote_bind_address=('MyUSERNAME.mysql.pythonanywhere-services.com', 3306)
) as tunnel:
do_all_processing()
def do_all_processing():
connection = MySQLdb.connect(
user='MyUSERNAME',
passwd='***',
host='127.0.0.1', port=tunnel.local_bind_port,
db='MyUSERNAME$liveSports',
)
...etc...

Related

MySQL (MariaDB) [WinError 10053] An established connection was aborted by the software in your host machine

So, I'm struggling with mysql
I tried to use mysql.connector, though it turned out that it doesn't really want to cooperate when I'm connecting via sshtunnel
So I transfered to pymysql, and here's the most basic code I was able to write:
import pymysql
from sshtunnel import SSHTunnelForwarder
with SSHTunnelForwarder(('192.168.0.x', 22), ssh_username='pi', ssh_password='*********', remote_bind_address=('localhost', 3306)) as tunnel:
tunnel.start()
mydb = pymysql.connect(host="localhost",
user='Mashu',
passwd='******',
port=tunnel.local_bind_port,
db='Special_Channels')
print(mydb)
query = "SELECT * FROM Daily"
cur = mydb.cursor()
data = cur.execute(query)
print(data)
Though on
cur = mydb.cursor()
it raises an error:
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
Also on a higher level it is:
pymysql.err.OperationalError: (2013, 'Lost connection to MySQL server during query ([WinError 10053] An established connection was aborted by the software in your host machine)')
I'm sure the database and table existst, and that this mysql account is accessible, as I have it opened and made changes to it in other software (DataGrip if anyone wonders)
I suggest mariadb instead of pymysql for your case
pip install mariadb
Solution is pretty easy.
it should all be inside with statement as tunnel connection (therefore database access) is closed outside statement, so it should look like this:
import pymysql
from sshtunnel import SSHTunnelForwarder
with SSHTunnelForwarder(('192.168.0.x', 22), ssh_username='pi', ssh_password='*********', remote_bind_address=('localhost', 3306)) as tunnel:
tunnel.start()
mydb = pymysql.connect(host="localhost",
user='Mashu',
passwd='******',
port=tunnel.local_bind_port,
db='Special_Channels')
print(mydb)
query = "SELECT * FROM Daily"
cur = mydb.cursor()
data = cur.execute(query)
print(data)

Python update query in mariadb

I am trying to update my mariadb table via python code .While compile the query nothing happen in my database. please check below code and let me know where i made mistake in update function
import mariadb
connection= mariadb.connect(user="user1", database="db1", host="ippp" ,password="pass")
cursor= connection.cursor()
cursor.execute("UPDATE product_options_combinations SET quantity=5944 WHERE item_code ='31628'")
cursor.close()
connection.close()
Hello here I have a clean code example for you. How to update it.
import pymysql
# Create a connection object
# IP address of the MySQL database server
Host = "localhost"
# User name of the database server
User = "user"
# Password for the database user
Password = ""
database = "GFG"
conn = pymysql.connect(host=Host, user=User, password=Password, database)
# Create a cursor object
cur = conn.cursor()
query = f"UPDATE PRODUCT SET price = 1400 WHERE PRODUCT_TYPE = 'broadband'"
cur.execute(query)
#To commit the changes
conn.commit()
conn.close()
You just need to add connection.commit() to your code, but I recommend you use a parametrized SQL preferably with a list of tuples,more of which might be added if needed, along with cursor.executemany() as being more performant for DML statements such as
import mariadb
connection= mariadb.connect(user="user1",
password="pass",
host="ippp",
port=3306,
database="db1")
cursor= connection.cursor()
dml="""
UPDATE product_options_combinations
SET quantity=%s
WHERE item_code =%s
"""
val=[
(5944,'31628')
]
cursor.executemany(dml,val)
connection.commit()
cursor.close()
connection.close()
Are you sure that the connection is working properly?
Have you tried to implement a try and catch routine to print mariadb errors?
Something like this:
# Connect to MariaDB Platform
import mariadb
try:
conn = mariadb.connect(
user="user",
password="password",
host="xx.xx.xx.xx",
port=3306,
database="db_name"
)
except mariadb.Error as e:
print(f"Error connecting to MariaDB Platform: {e}")
sys.exit(1)

Connect to MySQL on GCE using Google Colaboratory

I am trying to access MySQL on GCE VM instance through Google Colaboratory though, unfortunately, it does not work properly but does work in the local VSCode environment.
While executing TestExec.py, it shows SSH Connected so it seems that ssh connection is successfully done though, however, it seems to be stuck on MySQL connection.
Output on Google Colab:
Please help with the solutions/tips?
sqlList = []
sqlList.append("select * from table name;")
HOST = 'ComputeEngine PublicIP'
PORT = 22
USER = 'username'
DBUSER = 'username for db'
KEY_FILE = 'private key file path'
DBNAME = 'dbname'
DBPORT = 3306
SSH_BASTION_ADDRESS = HOST
SSH_PORT = PORT
SSH_USER = USER
SSH_PKEY_PATH = KEY_FILE
MYSQL_HOST = HOST
MYSQL_PORT = 3306
MYSQL_USER = DBUSER
MYSQL_PASS = 'MySQL Login PW'
MYSQL_DB = DBNAME
with SSHTunnelForwarder(
(SSH_BASTION_ADDRESS, SSH_PORT),
ssh_pkey=SSH_PKEY_PATH,
ssh_username=SSH_USER,
# ssh_password=PASSPHRASE,
remote_bind_address=('localhost', MYSQL_PORT),
local_bind_address=('localhost', MYSQL_PORT)
) as ssh:
print("SSH Connected")
print(ssh.local_bind_port)
try:
connection = mysql.connector.connect(
host='localhost',
port = ssh.local_bind_port,
user=MYSQL_USER,
passwd=MYSQL_PASS,
db=MYSQL_DB,
charset='utf8'
)
print(connection.is_connected())
print("DB Connected")
cur = connection.cursor()
sql = "use dbname"
cur.execute(sql)
# rows = cur.fetchall()
# for row in rows:
# print(row)
for i in range(len(sqlList)):
print(sqlList[i])
sql = str(sqlList[i])
# sql = 'create table test (id int, content varchar(32))'
cur.execute(sql)
rows = cur.fetchall()
for row in rows:
print(row)
except mysql.connector.Error as err:
print("Something went wrong: {}".format(err))
connection.rollback()
raise err
finally:
cur.close()
connection.commit()
connection.close()
It seemed the error occurred because of the connection. I have changed the method of connection.
import pymysql.cursors
connection = pymysql.connect(
host='localhost',
user='user',
password='password!',
db='dbname',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor
)

Database is not reachable - pymysql

After reading many thread here i didn't resolved my problem, my code works with a free database created in this website (freemysqlhosting.net), but it doesn't work with my own database on a hosting webiste. My code ('******' for privacy):
#!/usr/bin/python3
import pymysql
db = pymysql.connect("sql.******.it", "******", "******", "******")
cursor = db.cursor()
cursor.execute("SELECT * FROM users")
results = cursor.fetchall()
print(results)
db.close()
Here the error:
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'sql.******.it' ([Errno 101] Network is unreachable)")
From command line I would use ping, and then nc. I mean, just cut things to minimum, an check if that works. So first validate if host is valid, and your host can resolve it to IP. Next check if you can connect to that host, on provided port. Here is sample in python.
If I have to bet - I would say, you are missing port... Just double check all names, docs provided by the hosting.
Have you tried using mysql.connector? That's what I use maybe it will work
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
passwd="yourpassword"
)
mycursor = mydb.cursor()
mycursor.execute("SELECT * FROM customers")
myresult = mycursor.fetchall()
for x in myresult:
print(x)

Enable Python to Connect to MySQL via SSH Tunnelling

I'm using MySqldb with Python 2.7 to allow Python to make connections to another MySQL server
import MySQLdb
db = MySQLdb.connect(host="sql.domain.com",
user="dev",
passwd="*******",
db="appdb")
Instead of connecting normally like this, how can the connection be made through a SSH tunnel using SSH key pairs?
The SSH tunnel should ideally be opened by Python. The SSH tunnel host and the MySQL server are the same machine.
Only this worked for me
import pymysql
import paramiko
import pandas as pd
from paramiko import SSHClient
from sshtunnel import SSHTunnelForwarder
from os.path import expanduser
home = expanduser('~')
mypkey = paramiko.RSAKey.from_private_key_file(home + pkeyfilepath)
# if you want to use ssh password use - ssh_password='your ssh password', bellow
sql_hostname = 'sql_hostname'
sql_username = 'sql_username'
sql_password = 'sql_password'
sql_main_database = 'db_name'
sql_port = 3306
ssh_host = 'ssh_hostname'
ssh_user = 'ssh_username'
ssh_port = 22
sql_ip = '1.1.1.1.1'
with SSHTunnelForwarder(
(ssh_host, ssh_port),
ssh_username=ssh_user,
ssh_pkey=mypkey,
remote_bind_address=(sql_hostname, sql_port)) as tunnel:
conn = pymysql.connect(host='127.0.0.1', user=sql_username,
passwd=sql_password, db=sql_main_database,
port=tunnel.local_bind_port)
query = '''SELECT VERSION();'''
data = pd.read_sql_query(query, conn)
conn.close()
I'm guessing you'll need port forwarding. I recommend sshtunnel.SSHTunnelForwarder
import mysql.connector
import sshtunnel
with sshtunnel.SSHTunnelForwarder(
(_host, _ssh_port),
ssh_username=_username,
ssh_password=_password,
remote_bind_address=(_remote_bind_address, _remote_mysql_port),
local_bind_address=(_local_bind_address, _local_mysql_port)
) as tunnel:
connection = mysql.connector.connect(
user=_db_user,
password=_db_password,
host=_local_bind_address,
database=_db_name,
port=_local_mysql_port)
...
from sshtunnel import SSHTunnelForwarder
import pymysql
import pandas as pd
tunnel = SSHTunnelForwarder(('SSH_HOST', 22), ssh_password=SSH_PASS, ssh_username=SSH_UNAME,
remote_bind_address=(DB_HOST, 3306))
tunnel.start()
conn = pymysql.connect(host='127.0.0.1', user=DB_UNAME, passwd=DB_PASS, port=tunnel.local_bind_port)
data = pd.read_sql_query("SHOW DATABASES;", conn)
credits to https://www.reddit.com/r/learnpython/comments/53wph1/connecting_to_a_mysql_database_in_a_python_script/
If your private key file is encrypted, this is what worked for me:
mypkey = paramiko.RSAKey.from_private_key_file(<<file location>>, password='password')
sql_hostname = 'sql_hostname'
sql_username = 'sql_username'
sql_password = 'sql_password'
sql_main_database = 'sql_main_database'
sql_port = 3306
ssh_host = 'ssh_host'
ssh_user = 'ssh_user'
ssh_port = 22
with SSHTunnelForwarder(
(ssh_host, ssh_port),
ssh_username=ssh_user,
ssh_pkey=mypkey,
ssh_password='ssh_password',
remote_bind_address=(sql_hostname, sql_port)) as tunnel:
conn = pymysql.connect(host='localhost', user=sql_username,
passwd=sql_password, db=sql_main_database,
port=tunnel.local_bind_port)
query = '''SELECT VERSION();'''
data = pd.read_sql_query(query, conn)
print(data)
conn.close()
You may only write the path to the private key file: ssh_pkey='/home/userName/.ssh/id_ed25519' (documentation is here: https://sshtunnel.readthedocs.io/en/latest/).
If you use mysql.connector from Oracle you must use a construction
cnx = mysql.connector.MySQLConnection(...
Important: a construction
cnx = mysql.connector.connect(...
does not work via an SSh! It is a bug.
(The documentation is here: https://dev.mysql.com/doc/connector-python/en/connector-python-connectargs.html).
Also, your SQL statement must be ideal. In case of an error on SQL server side, you do not receive an error message from SQL-server.
import sshtunnel
import numpy as np
with sshtunnel.SSHTunnelForwarder(ssh_address_or_host='ssh_host',
ssh_username="ssh_username",
ssh_pkey='/home/userName/.ssh/id_ed25519',
remote_bind_address=('localhost', 3306),
) as tunnel:
cnx = mysql.connector.MySQLConnection(user='sql_username',
password='sql_password',
host='127.0.0.1',
database='db_name',
port=tunnel.local_bind_port)
cursor = cnx.cursor()
cursor.execute('SELECT * FROM db_name.tableName;')
arr = np.array(cursor.fetchall())
cursor.close()
cnx.close()
This works for me:
import mysql.connector
import sshtunnel
with sshtunnel.SSHTunnelForwarder(
('ip-of-ssh-server', 'port-in-number-format'),
ssh_username = 'ssh-username',
ssh_password = 'ssh-password',
remote_bind_address = ('127.0.0.1', 3306)
) as tunnel:
connection = mysql.connector.connect(
user = 'database-username',
password = 'database-password',
host = '127.0.0.1',
port = tunnel.local_bind_port,
database = 'databasename',
)
mycursor = connection.cursor()
query = "SELECT * FROM datos"
mycursor.execute(query)
Someone said this in another comment. If you use the python mysql.connector from Oracle then you must use a construction cnx = mysql.connector.MySQLConnection(....
Important: a construction cnx = mysql.connector.connect(... does not work via an SSH! This bug cost me a whole day trying to understand why connections were being dropped by the remote server:
with sshtunnel.SSHTunnelForwarder(
(ssh_host,ssh_port),
ssh_username=ssh_username,
ssh_pkey=ssh_pkey,
remote_bind_address=(sql_host, sql_port)) as tunnel:
connection = mysql.connector.MySQLConnection(
host='127.0.0.1',
port=tunnel.local_bind_port,
user=sql_username,
password=sql_password)
query = 'select version();'
data = pd.read_sql_query(query, connection)
print(data)
connection.close()
If you are using python, and all the username, password, host and port are correct then there is just one thing left, that is using the argument (use_pure=True). This argument uses python to parse the details and password. You can see the doc of mysql.connector.connect() arguments.
with sshtunnel.SSHTunnelForwarder(
(ssh_host,ssh_port),
ssh_username=ssh_username,
ssh_pkey=ssh_pkey,
remote_bind_address=(sql_host, sql_port)) as tunnel:
connection = mysql.connector.MySQLConnection(
host='127.0.0.1',
port=tunnel.local_bind_port,
user=sql_username,
password=sql_password,
use_pure='True')
query = 'select version();'
data = pd.read_sql_query(query, connection)
print(data)
connection. Close()
Paramiko is the best python module to do ssh tunneling. Check out the code here:
https://github.com/paramiko/paramiko/blob/master/demos/forward.py
As said in comments this one works perfect.
SSH Tunnel for Python MySQLdb connection
Best practice is to parameterize the connection variables.
Here is how I have implemented. Works like charm!
import mysql.connector
import sshtunnel
import pandas as pd
import configparser
config = configparser.ConfigParser()
config.read('c:/work/tmf/data_model/tools/config.ini')
ssh_host = config['db_qa01']['SSH_HOST']
ssh_port = int(config['db_qa01']['SSH_PORT'])
ssh_username = config['db_qa01']['SSH_USER']
ssh_pkey = config['db_qa01']['SSH_PKEY']
sql_host = config['db_qa01']['HOST']
sql_port = int(config['db_qa01']['PORT'])
sql_username = config['db_qa01']['USER']
sql_password = config['db_qa01']['PASSWORD']
with sshtunnel.SSHTunnelForwarder(
(ssh_host,ssh_port),
ssh_username=ssh_username,
ssh_pkey=ssh_pkey,
remote_bind_address=(sql_host, sql_port)) as tunnel:
connection = mysql.connector.connect(
host='127.0.0.1',
port=tunnel.local_bind_port,
user=sql_username,
password=sql_password)
query = 'select version();'
data = pd.read_sql_query(query, connection)
print(data)
connection.close()

Categories

Resources