I have read the Flask documentation and Python documentation to try to understand what these codes do. I know that it is initialise the Database but would like to know in very detail and with normal language, easy language for beginner.
Can anyone please explain me about this?
import sqlite3
from contextlib import closing
DATABASE = 'flaskr.db'
def connect_db():
return sqlite3.connect(app.config[’DATABASE’])
def init_db():
with closing(connect_db()) as db:
with app.open_resource(’schema.sql’, mode=’r’) as f:
db.cursor().executescript(f.read())
db.commit()
import sqlite3
Imports Data base connectors
from contextlib import closing
No idea why its used.
Documentetion here
DATABASE = 'flaskr.db'
Defines database,in this case it is a db file.
def connect_db():
return sqlite3.connect(app.config[’DATABASE’])
Connect DB method which returns a sqlite3 connection, using sqlite3 import and invoking connect() on it.
Hint: try >>> dir(sqlite3) after importing in your python console
def init_db():
with closing(connect_db()) as db:
with app.open_resource(’schema.sql’, mode=’r’) as f:
db.cursor().executescript(f.read())
db.commit()
Initialize database method, it takes a schema.sql and executes it on DB by f.read method.
After executing you need to commit changes to db, hence db.commit()
You can find it explained clearly here
Related
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.
SQLite objects created in a thread can only be used in that same thread.
app = Flask(__name__)
#app.route("/test/")
def test():
conn = sqlite3.connect("god_attributes.db")
c = conn.cursor()
c.execute("SELECT * FROM god_icon_table")
all = c.fetchall()
return render_template("test.html", all = all)
I'm making a flask app and I have a lot of methods that need to pull data from a db using SQL db calls. I am wondering if I can store methods somewhere else and call them by importing to organize things. Basically I want the entire app route for test to be like this:
app = Flask(__name__)
#app.route("/test/")
def test():
all = get_all()
return render_template("test.html", all = all)
where get_all() does everything from conn to fetchall in the first code sample
So I figured out a structural solution. Wasnt able to place a get_all() method that does the SQL commands directly. I made a new json file from the database and used that json to get the information
This is probably a stupid question but I cannot find the information in the documentation for pymysql. What is the pymysql default cursorclass? When I do not specify a cursor class on connection to the database my queries return a list for each row in the response.
When I specify pymysql.cursors.DictCursor I get a dictionary response. I would like to be able to change between them for different connections within a script.
I've written a little function with a context manager to yield the cursor but it requires me to specify the name of the cursorclass each time. I know I can get around this, but knowing the name of the default cursorclass would be nice.
from contextlib import contextmanager
import pymysql
#contextmanager
def openDb(host=DB_HOST, database=DB_DATABASE,
user=DB_USER, cursor=DB_CURSOR):
"""
Simple context manager for opening a db connection
"""
with pymysql.connect(host=host, database=database, user=user,
cursorclass=cursor) as cur:
yield cur
I could probably write this as:
#contextmanager
def openDb(host=DB_HOST, database=DB_DATABASE,
user=DB_USER, cursor=None):
"""
Simple context manager for opening a db connection
"""
if cursor:
with pymysql.connect(host=host, database=database, user=user,
cursorclass=cursor) as cur:
yield cur
else:
with pymysql.connect(host=host, database=database, user=user) as cur:
yield cur
and let it default to whatever the default cursorclass is, but I would prefer to be explicit.
Of course as soon as I post this I find the answer in via:
>>> import pymysql
>>> help(pymysql.cursors)
Help on module pymysql.cursors in pymysql:
NAME
pymysql.cursors - # -*- coding: utf-8 -*-
CLASSES
builtins.object
Cursor
SSCursor
DictCursorMixin
DictCursor(DictCursorMixin, Cursor)
SSDictCursor(DictCursorMixin, SSCursor)
pymysql.cursors.Cursor is the answer. Documentation...
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
I am used to (spoiled by?) python's SQLite interface to deal with SQL databases. One nice feature in python's SQLite's API the "context manager," i.e., python's with statement. I usually execute queries in the following way:
import as sqlite
with sqlite.connect(db_filename) as conn:
query = "INSERT OR IGNORE INTO shapes VALUES (?,?);"
results = conn.execute(query, ("ID1","triangle"))
With the code above, if my query modifies the database and I forget to run conn.commit(),the context manager runs it for me automatically upon exiting the with statement. It also handles exceptions nicely: if an exception occurs before I commit anything, then the database is rolled back.
I am now using the MySQLdb interface, which doesn't seem to support a similar context manager out of the box. How do I create my own? There is a related question here, but it doesn't offer a complete solution.
Previously, MySQLdb connections were context managers.
As of this commit on 2018-12-04, however, MySQLdb connections are no longer context managers,
and users must explicitly call conn.commit() or conn.rollback(), or write their own context manager, such as the one below.
You could use something like this:
import config
import MySQLdb
import MySQLdb.cursors as mc
import _mysql_exceptions
import contextlib
DictCursor = mc.DictCursor
SSCursor = mc.SSCursor
SSDictCursor = mc.SSDictCursor
Cursor = mc.Cursor
#contextlib.contextmanager
def connection(cursorclass=Cursor,
host=config.HOST, user=config.USER,
passwd=config.PASS, dbname=config.MYDB,
driver=MySQLdb):
connection = driver.connect(
host=host, user=user, passwd=passwd, db=dbname,
cursorclass=cursorclass)
try:
yield connection
except Exception:
connection.rollback()
raise
else:
connection.commit()
finally:
connection.close()
#contextlib.contextmanager
def cursor(cursorclass=Cursor, host=config.HOST, user=config.USER,
passwd=config.PASS, dbname=config.MYDB):
with connection(cursorclass, host, user, passwd, dbname) as conn:
cursor = conn.cursor()
try:
yield cursor
finally:
cursor.close()
with cursor(SSDictCursor) as cur:
print(cur)
connection = cur.connection
print(connection)
sql = 'select * from table'
cur.execute(sql)
for row in cur:
print(row)
To use it you would place config.py in your PYTHONPATH and define the HOST, USER, PASS, MYDB variables there.
Think things have changed since this question was originally asked. Somewhat confusingly (from my point of view at least), for recent versions of MySQLdb, if you use a connection in a context you get a cursor (as per the oursql example), not something that closes automatically (as you would if you opened a file for instance).
Here's what I do:
from contextlib import closing
with closing(getConnection()) as conn: #ensure that the connection is closed
with conn as cursor: #cursor will now auto-commit
cursor.execute('SELECT * FROM tablename')