CherryPy and MySQL can't connect to the database - python

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()

Related

In python flask with mysql, can I use the same connection throught the app life cycle?

Here is my python flask code:
from flask import *
import mysql.connector
app = Flask(__name__)
conn = mysql.connector.connect(
host="<my db host>",
user="<my db user>",
password = "<my db password>",
database = '<my db>'
)
#app.route('/posts/<int:post_id>')
def get_post(post_id):
with conn.cursor(dictionary=True) as cur:
cur.execute('select * from posts where ID=%s',(post_id,))
result = cur.fetchone()
ans=result['post_content']
return ans
app.run(debug=False,threaded=True,host='0.0.0.0',port=80)
Note how I don't create a new connection for each request. Instead, I use the same connection for all requests.
My question is: is there any potential problems in this approach?
You should not use the same connection, because it will stay open forever, only open an SQL connection when you need to use it, and close it afterward. Not doing so can lead to a lot of errors.

Configuration handling in Flask for MySQL database connection

I am new to Flask and currently exploring the official tutorial available in https://flask.palletsprojects.com/en/2.0.x/tutorial/factory/.
The example creates a blog based on a SQLite database. The database is defined in the following statement:
app.config.from_mapping(
SECRET_KEY='dev',
DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'),
)
Program Code
flaskr/__init__.py
import os
from flask import Flask
def create_app(test_config=None):
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
app.config.from_mapping(
SECRET_KEY='dev',
DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'),
)
if test_config is None:
# load the instance config, if it exists, when not testing
app.config.from_pyfile('config.py', silent=True)
else:
# load the test config if passed in
app.config.from_mapping(test_config)
# ensure the instance folder exists
try:
os.makedirs(app.instance_path)
except OSError:
pass
# a simple page that says hello
#app.route('/hello')
def hello():
return 'Hello, World!'
return app
However, instead of am SQLite database, I want to use a MySQL database for storing information. How can I define the MySQL configuration at this stage?
I have modified the following code in the db.py file of the tutorial:
https://flask.palletsprojects.com/en/2.0.x/tutorial/database/
import mysql.connector
import click
from flask import current_app, g
from flask.cli import with_appcontext
# Function to create a database connection.
def get_db():
if 'db' not in g:
g.db=mysql.connector.connect(host="localhost",user="dbuser",password="database123",database="testdb")
return g.db
# Function to close an existing database connection.
def close_db(e=None):
db=g.pop('db',None)
if db is not None:
db.close()
# Function to initialize the database from a script.
def init_db():
db = get_db()
with open('schema.sql', 'r') as f:
with db.cursor() as cursor:
cursor.execute(f.read(), multi=True)
db.commit()
#click.command('init-db')
#with_appcontext
def init_db_command():
# Delete existing data and re-create tables.
init_db()
click.echo('Initialized the database.')
# Register with the application.
def init_app(app):
app.teardown_appcontext(close_db)
app.cli.add_command(init_db_command)
Can someone please provide some guidance on how to setup a MySQL database connection?
I did some digging around and figured that it is not mandatory to define the MySQL database connection inside the factory function for the application to work. I removed the database parameter values from app.config.from_mapping and only kept the database connection string inside the actual db.py file. So far, the application has been working fine.
app=Flask(__name__, instance_relative_config=True)
app.config.from_mapping(SECRET_KEY='development',)
Here you can use pymysql to manage your connections. Below is an example showing that how you can manage the DB connection.
import pymysql
def db_connect():
conn = pymysql.connect(user='Your user',
password="Your password",
host="Your host",
database="Your database",
cursorclass=pymysql.cursors.DictCursor)
return conn
def db_close(conn):
if conn and conn.open:
conn.close()
class DatabaseHandler(object):
def __init__(self):
self.conn = None
def __enter__(self):
self.conn = db_connect()
return self.conn
def __exit__(self, exc_type, exc_val, exc_tb):
db_close(self.conn)
You can use it as,
with DatabaseHandler() as db_conn:
Any database operation with db_conn

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()

Is it required to close python SQL connection in Flask app?

I've the code like this below. Is it necessary to close mysql connection because whenever my home page is requested, a new sql connection will be created?
I randomly get Connection Limit error. But I'm not sure if the DB connection is the problem.
#app.route("Home", methods=["GET"])
def get_home_page():
db = mysql.connect(host, user, password, db_name, charset='utf8', use_unicode=True)
...
It is good practice to close the connection. You can put your codes inside a try..finally block.
#app.route("Home", methods=["GET"])
def get_home_page():
db = mysql.connect(host, user, password, db_name, charset='utf8', use_unicode=True)
try:
... do something ...
finally:
db.close()
from my experience, close session after use it take significant difference amount of time to response in api whom i've experienced in flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
try:
db.session.query( Any Model ...
except:
finally:
db.close_all_sessions

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