Mysql connection with python in a class - python

i'm trying to connect to a database building a class connection()saved in local folder in file utils.py .This is what i worked so far of it:
class connection:
def __init__(self):
self.conn = MySQLdb.connect(host = "localhost",user = "xxx",
passwd = "xxx", db = "xxx",
cursorclass=MySQLdb.cursors.DictCursor)
def TearDown(self):
self.conn.close()
def nume(self):
return self.conn
and this is where i use it in code:
from utils import execute_sql,connection
con = connection.nume()
cursor = con.cursor()
....
cursor.execute(sql)
...
connection.TearDown()
i tryed several more but this way was the simplest, still getting some errors that i struggle with;

The glaring issue is that you need to instantiate your "connection" class before calling methods.
from utils import execute_sql,connection
my_con = connection()
con = my_con.nume()
cursor = con.cursor()
....
cursor.execute(sql)
...
connection.TearDown()
As a side note - your connection class seems a bit superfluous.

Related

Python 3 - Weak reference error on cursor when using MySQL connector

Having trouble understanding whats wrong with some pretty basic Python 3 code. Its a database class using MySQL connector which is then inherited in another class.
The database class (database.py):
import mysql.connector
config = {
'host': 'localhost',
'user': '...',
'password': '...',
'database': '...'
}
class Database:
def __init__(self):
self.connect()
def connect(self):
try:
db = mysql.connector.connect(**config)
self.cursor = db.cursor()
except mysql.connector.Error as err:
print(err.msg)
return False
The class that inherits the database class:
import mysql.connector
import datetime
from database import Database
class Logger(Database):
def __init__(self):
super().__init__()
def get_row(self, id):
try:
sql = ("SELECT * FROM logs WHERE id = %s")
self.cursor.execute(sql, (id,))
result = cursor.fetchone()
return result
except mysql.connector.Error as err:
print(err.msg)
return False
And the calling code ...
obj = Logger()
data = obj.get_row(2)
The weak reference error (on cursor):
Traceback (most recent call last):
File "examples.py", line 71, in <module>
data = obj.get_row(2)
File "examples.py", line 28, in get_row
self.cursor.execute(sql, (id,))
ReferenceError: weakly-referenced object no longer exists
What am I not understanding here? I know the error is specific to the use of the MySQL connector as I have read that it uses weak references. I am just confused as to how I can reuse / maintain a reference to the cursor attribute of the parent class properly in my inherited class methods. Thanks in advance!

Python class attribute cannot be called within object scope

import pyodbc
class Database(object):
def connect(self):
connection = pyodbc.connect("""DRIVER={SQL Server};
SERVER=XX\SQLEXPRESS;
DATABASE=ACCOUNT_DBF;
UID=sa;PWD=XXX""")
cursor = connection.cursor()
def check_account(self, usr):
cursor.execute("SELECT * FROM ACCOUNT_TBL WHERE account = ?", usr)
row = cursor.fetchone()
print(row[0])
database = Database()
database.check_account("developer")
So, as you can see I am trying to call the "check_account" function with the parameter of "developer". But whenever I execute/build it, it gives me an error of
"NameError: name cursor not defined"
I am curious and new to python on how to actually do it. I've been searching around the web but I cannot find a specific answer for my problem.
*I am using the latest python btw(3.6.1).
The NameError exception is triggered because in the check_account method you can not see local variables defined in connect method.
You need to set instance attributes "inside" self, since you can access self from all methods (it is the instance itself).
def connect(self):
self.connection = pyodbc.connect("""DRIVER={SQL Server};
SERVER=XX\SQLEXPRESS;
DATABASE=ACCOUNT_DBF;
UID=sa;PWD=XXX""")
self.cursor = connection.cursor()
def check_account(self, usr):
self.cursor.execute("SELECT * FROM ACCOUNT_TBL WHERE account = ?", usr)
row = self.cursor.fetchone()
print(row[0])
Try:
class Database(object):
def connect(self):
connection = pyodbc.connect("""DRIVER={SQL Server};
SERVER=XX\SQLEXPRESS;
DATABASE=ACCOUNT_DBF;
UID=sa;PWD=XXX""")
self.cursor = connection.cursor()
In your code, cursoris variable which below to method, only self.cursor can store cursor to class, and then other methods can use.

Connect to SQL server from self made module

I currently have many scripts that connect to the same MSSQL database. I make the connection in each of the scripts, but for ease of use I want to put the connection in a module and call that module from my script. The code in my module connect_to_db.pyc looks like this:
import pyodbc
def sql_connect():
server="some_server.net"
port="1433"
user = "my_username#my_domain"
server="my_server"
database="my_database"
conn = pyodbc.connect('DRIVER={SQL Server};SERVER=my_server,1433',
user=user,
password=password,
database=database)
c=conn.cursor()
Then, in my script I try to call this module and run a query:
from connect_to_db import sql_connect
sql_connect()
c.execute("SELECT * FROM table")
I get the error that the name c is not defined. I tried to define it as a global too, but it don't help. It must have something to do with my lack of understanding modules, but I can't figure out what.
You can return cursor in your sql_connect function
import pyodbc
def sql_connect():
server="some_server.net"
port="1433"
user = "my_username#my_domain"
server="my_server"
database="my_database"
conn = pyodbc.connect('DRIVER={SQL Server};SERVER=my_server,1433',
user=user,
password=password,
database=database)
return conn.cursor()
And then you can use it as
from connect_to_db import sql_connect
c = sql_connect()
c.execute("SELECT * FROM table")
You are indeed missing a bit there:
in your function sql_connect, you assign to a local variable named c.
That variable is not existant outside your function.
If you want a connection variable to exist on module level, maybe try the following attempt:
In your "connect_to_db.py":
import pyodbc
def sql_connect():
server="some_server.net"
port="1433"
user = "my_username#my_domain"
server="my_server"
database="my_database"
conn = pyodbc.connect('DRIVER={SQL Server};SERVER=my_server,1433',
user=user,
password=password,
database=database)
return conn.cursor()
cursor = sql_connect()
This creates a varibale "cursor" on the level of the module.
In another module, simply perform
from connect_to_db import cursor
to import the module's "cursor" member.
This should do the trick.
Hint: Please be advised that this approach may not be very elegant, in terms of software-engineering.
Edit:
Maybe, you may want to dive deeper into object-oriented programming?
class MSSQLConnector(object):
def __init__(self, server, port, database, user, password):
self.server = server
self.port = port
self.conn = pyodbc.connect('DRIVER={SQL Server};SERVER='{0},
{1}.format((self.server, self.port)), user, password, database)
def open_cursor(self):
return self.conn.cursor()
Which would be used in this fashion:
connector = MSSQLConnector("my_server", "1433", "my_database", "username", "secret-password")
cursor = connector.open_cursor()

CherryPy and MySQL can't connect to the database

I have a CherryPy "site" set up under Apache with modwsgi. It works fine and I can return hello world messages no problem. The problem is when I try to connect to my MySQL database. Here is the code I'm using.
import sys
sys.stdout = sys.stderr
import atexit
import threading
import cherrypy
import MySQLdb
cherrypy.config.update({'environment': 'embedded'})
if cherrypy.__version__.startswith('3.0') and cherrypy.engine.state == 0:
cherrypy.engine.start(blocking=False)
atexit.register(cherrypy.engine.stop)
def initServer():
global db
db=MySQLdb.connect(host="localhost", user="root",passwd="pass",db="Penguin")
class Login(object):
def index(self):
return 'Login Page'
index.exposed = True
class Root(object):
login = Login();
def index(self):
# Sample page that displays the number of records in "table"
# Open a cursor, using the DB connection for the current thread
c=db.cursor()
c.execute('SELECT count(*) FROM Users')
result=cursor.fetchall()
cursor.close()
return 'Help' + result
index.exposed = True
application = cherrypy.Application(Root(), script_name=None, config=None)
Most of this was copied from the CherryPy site on setting up modwsgi, I just added the database stuff which I pieced together from various internet sources.
When I try to view the root page I get a 500 Internal Server Error. I can still get to the login page fine but so I'm pretty sure I'm messing up the database connection somehow.
You have a bunch of errors, not related to CherryPy really.
def initServer():
global db
db is not defined in the global scope. Try:
db = None
def initServer():
global db
In addition, initServer() is never called to create the DB connection.
Another:
c = db.cursor()
c.execute('SELECT count(*) FROM Users')
result = cursor.fetchall()
cursor.close()
cursor is not defined. I think you mean c:
c = db.cursor()
c.execute('SELECT count(*) FROM Users')
result = c.fetchall()
c.close()

Closing cursor and connection with Python and MySQLdb

I have a simple web.py-based app that uses MySQLdb. I have a class that handles database operations like so:
class db():
def __init__(self):
db = MySQLdb.connect(host='mysql.server', user='user', passwd='pass', db='app')
self.cur = db.cursor()
def get_data(self):
sql = "SELECT * FROM foobar"
self.cur.execute(sql)
rs = self.cur
r.fetchall()
return rs
I instantiate the class like so DB = db(). Then, in another class, I will refer to it.
class bleh()
def blarg():
DB.get_data()
With something like this, where would I close the cursor and connection? Or am I approaching this completely wrong?
db.close() for connection and cur.close() for cursor.
http://mysql-python.sourceforge.net/MySQLdb.html
EDIT:
But if it give it a bit thought - you won't need to close cursor. Python closes the cursor once the variable is destroyed, so when the instance of your class does not exist anymore -- cursor will be closed.
First of all use different names for class-name and variable as you have used same name ('db') for class-name and connection as well.
Next, you need to define conn (in your question db line no 3) as self.conn.
import MySQLdb
class db():
def __init__(self):
self.conn = MySQLdb.connect(host='mysql.server', user='user', passwd='pass', db='app')
self.cur = self.conn.cursor()
def get_data(self):
sql = "SELECT * FROM test"
self.cur.execute(sql)
rs = self.cur
rs.fetchall()
return rs
class bleh()
def blarg():
data = DB.get_data()
DB.cur.close()
DB.conn.close()
Note: If you have multiple functions in class bleh to get data from database make sure that you close cursor and connection in function, which is to called in last. Or you may have a seperate function, which closes cursor and connection.

Categories