How do I connect functions between multiple databases? - python

When it comes to functions that require database access, I'm trying to figure out how to configure a connection between multiple MySQL databases; one existing in main.py and the other in test.py. So that when I import functions from main.py to test.py the functions execute against the test database.
This is my first time working with MySQL/Python Connector so I'm not sure how to achieve this.
main.py
import mysql.connector
def database_connect(func):
def wrapper_db_connect():
with mysql.connector.connect(user=user, password=password, database=db)
return func()
return wrapper_db_connect
#database_connect
def select_listing(x=None):
pass
#database_connect
def insert_record():
pass

It's actually simpler than you'd imagine, you'd have to create a global mysql connector variable like so,
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword"
database = "databasename"
)
At which point you can use it as a parameter for your functions,
#main.py
def exampleFunc(mydb):
mycursor = mydb.cursor()
mycursor.execute("SELECT * FROM example")
return mycursor.fetchall()
#test.py
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword"
database = "test_database"
)
val = exampleFunction(mydb)

Related

Perform Sql queries without statement

So currently I'm able to perform mysql queries by simply doing
import mysql.connector
from mysql.connector import connect, Error
with connect(
host="localhost",
user="user",
password="password",
) as connection:
select_query = """
SELECT * FROM MY_TABLE
"""
with connection.cursor() as cursor:
cursor.execute(select_query)
Is there a way to do this but without the "SQL"
Something like this pseudo code
table = Table("MY_TABLE")
return table.select_all()

How to avoid writing "MySQLdb.connect" again and again?

I wonder if there is a way to avoid writing MySQLdb.connect(host='localhost', user='xyz', password='xyz', db='xyz')
again and again in Python?
Example:
def Add_New_User(self):
self.db = MySQLdb.connect(host='localhost', user='xyz', password='xyz', db='xyz')
self.cur = self.db.cursor()
after two or three lines (when new def is required and a lot of def is required), I need to write all over again the same string many times
def Add_New_User(self):
self.db = MySQLdb.connect(host='localhost', user='xyz', password='xyz', db='xyz')
self.cur = self.db.cursor()
I hope that there is a way to call it in a simple way, like a connection code written and saved in, e.g., MyConString.py then in the new def say, index.py, I would simply call the function MyConString.
Create a function called connection:
def conn(database):
import mysql.connector
connection = mysql.connector.connect(host='localhost',
database=database,
user='root',
password='yourpass')
cursor = connection.cursor(buffered=True)
return connection, cursor
Now, whenever you have to connect in any function do this:
def insert():
connection_data = conn("mydatabase")
connection = connection_data[0]
cursor = connection_data[1]
cursor.execute("show tables;")
connection.commit()
connection.close()
You can even make an entirely new script for functions that are repeatedly used to keep your main file clean.
Then you can just add import connections.py(say, that is your file name which contains conn() function)
# This is your main.py
import connections
def insert():
connection_data = connections.conn("mydatabase")
connection = connection_data[0]
cursor = connection_data[1]
cursor.execute("show tables;")
connection.commit()
connection.close()
Hope this helped!

Using a context manager with mysql connector python

I'm moving my code across from an sqlite database to mysql and I'm having a problem with the context manager, getting the following attribute error.
I've tried combinations of mydb.cursor() as cursor, mydb: etc...
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd="",
database="database_name"
cur = mydb.cursor()
with mydb as cursor:
AttributeError: __enter__
Python has a built-in way to implement a context manager if the object you're creating have a .close() method, by using the contextlib.closing context manager.
From the Python docs:
contextlib.closing(thing)
Return a context manager that closes thing upon completion of the block.
This is basically equivalent to:
from contextlib import contextmanager
#contextmanager
def closing(thing):
try:
yield thing
finally:
thing.close()
So, for your specific issue, you can use not only on the connection, but also the cursor.
Your code would be:
from contextlib import closing
import mysql.connector
query = "SELECT * FROM table"
db_conn_info = {
"user": "root",
"passwd": "",
"host": "localhost",
"port": 5000,
"database": "database_name"
}
with closing(mysql.connector.connect(**db_conn_info)) as conn:
with closing(conn.cursor()) as cur:
cur.execute(query)
result = cur.fetchall()
You have to define your own context manager as mysql.connector.connect is not a context manager.
Context managers have to be defined with __enter__ and __exit__ attributes.
It should be something like this. (Tested using psycopg2)
class DBConnection:
def __init__(self):
self.mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd="",
database="database_name"
)
self.cur = self.mydb.cursor()
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
# close db connection
self.mydb.connection.close()

mysql.connector doesn't detect outside changes to data

I have a script running which I want to process data when it's added to the database.
import mysql.connector
import time
wait_time = 2
mydb = mysql.connector.connect(
host="localhost",
user="xxx",
passwd="yyy",
database="my_database"
)
mycursor = mydb.cursor()
while True:
sql = "SELECT * FROM data WHERE processed = 0"
mycursor.execute(sql)
records = mycursor.fetchall()
for i, r in enumerate(records):
print(r)
time.sleep(wait_time)
However, if insert a row via different connection, this connection doesn't show it.
I.e. if I connect to my database via a third party app, and insert a row to
However if I restart the above script, it appears.
Any ideas?
Use a message queue (e.g. RabbitMQ). Get the third party App to use it. Message queue implementation has better APIs for processing information asynchronously. Even if you just use the message queue for storing the primary key of the database content.
Alternately enable binary logging and use a replication protocol library to process events.
I just faced the same error. and the easiest way to solve it is... defining mydb and mycursor inside the loop.
import mysql.connector
import time
wait_time = 2
while True:
mydb = mysql.connector.connect(
host="localhost",
user="xxx",
passwd="yyy",
database="my_database"
)
mycursor = mydb.cursor()
sql = "SELECT * FROM data WHERE processed = 0"
mycursor.execute(sql)
records = mycursor.fetchall()
for i, r in enumerate(records):
print(r)
time.sleep(wait_time)

using flags in Python MySQLdb

I want to use the python MySQLdb to access a remote MySQL server with --local-infile flag in order to be able to load data from a local file. (as mentioned in this question Importing CSV to MySQL table returns an error #1148)
I use
db = MySQLdb.connect(host="127.0.0.1", port=3307, user="someuser", passwd="password", db="sql_db")
to create a database connection. How do I mimic mysql -u username -p dbname --local-infile using MySQLdb
I know this is late for the initial question, but if someone comes here looking for the same you can do this:
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd="",
allow_local_infile=True,
)
Here you can check the docs for aditional flags: https://dev.mysql.com/doc/connector-python/en/connector-python-connectargs.html
If you want to set it as a DB config rather than in the connection, you can do it like this:
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd="",
)
mycursor = mydb.cursor()
try:
command = "SET GLOBAL local_infile = 'ON';"
mycursor.execute(command)
except mysql.connector.errors.DatabaseError:
pass
You can put your DB configurations in to a local file, and then read it when using.
config.ini
[MySQL]
host=192.168.20.28
user=root
password=123456
db_name=ovp_global
charset=utf8
py code:
import MySQLdb
import ConfigParser
config = ConfigParser.ConfigParser()
config.readfp(open("config.ini", "r"))
def get_connection():
host = config.get('MySQL', 'host')
user = config.get('MySQL', 'user')
passwd = config.get('MySQL', 'password')
db = config.get('MySQL', 'db_name')
charset = config.get('MySQL', 'charset')
return MySQLdb.connect(host=host, user=user, passwd=passwd, db=db, charset=charset)

Categories

Resources