Gab*_*lis 57 python sqlite flask
方法一:使用来自http://flask.pocoo.org/docs/tutorial/dbcon/和http://flask.pocoo.org/docs/patterns/sqlite3/的特殊g对象
import sqlite3
from flask import g
DATABASE = '/path/to/database.db'
def connect_db():
return sqlite3.connect(DATABASE)
@app.before_request
def before_request():
g.db = connect_db()
@app.teardown_request
def teardown_request(exception):
if hasattr(g, 'db'):
g.db.close()
Run Code Online (Sandbox Code Playgroud)
方法二:使用来自https://github.com/mitsuhiko/flask/blob/master/examples/flaskr/flaskr.py的 Mysterious _app_ctx_stack
from sqlite3 import dbapi2 as sqlite3
from flask import Flask, request, session, g, redirect, url_for, abort, \
render_template, flash, _app_ctx_stack
def get_db():
"""Opens a new database connection if there is none yet for the
current application context.
"""
top = _app_ctx_stack.top
if not hasattr(top, 'sqlite_db'):
top.sqlite_db = sqlite3.connect(app.config['DATABASE'])
return top.sqlite_db
@app.teardown_appcontext
def close_db_connection(exception):
"""Closes the database again at the end of the request."""
top = _app_ctx_stack.top
if hasattr(top, 'sqlite_db'):
top.sqlite_db.close()
Run Code Online (Sandbox Code Playgroud)
哪种方法更好?有什么不同?
Sea*_*ira 34
两者之间的区别在于方法一创建了g.db是否需要它的连接,而方法二只在您get_db在该应用程序上下文中第一次调用时创建连接.
如果你比较两者,使用这个设置:
yourapp = Flask(__name__)
# setup g.db or app_context here
# Add a logging statement (print will do)
# to the get_db or before_request functions
# that simply says "Getting the db connection ..."
# Then access / and /1
@yourapp.route("/")
def index():
return "No database calls here!"
@yourapp.route("/<int:post_id>")
def show_post(post_id):
# get a post using g.db or get_db
return "Went to the DB and got {!r}".format(post)
Run Code Online (Sandbox Code Playgroud)
您会看到当您/使用@app.before_requestsetup(g.db)时,无论您是否使用它都会获得连接,而在使用该_app_context路线时,您只能在通话时get_db获得连接.
公平地说,您还可以添加一个描述符来g执行相同的延迟连接(或者在现实生活中,从连接池获取连接).而在这两种情况下,你可以使用更多的魔法(werkzeug.local.LocalProxy准确地说)来创建自己的自定义线程局部行为像g,current_app和request(等等).
jpm*_*c26 12
第一个问题是即使在不需要连接时也会获得连接.第二种方法是使用第三方框架内部的缺点,而且它非常难以理解.
仅在这两个中,第二个可能是更好的选择.它不仅没有为不需要的路由获取连接,而且如果你沿着任何不需要的路径下去,它也不会获得连接,即使路由中的其他代码路径需要一个.(例如,如果您有一些表单验证,则只有在验证通过时才需要连接;当验证失败时,这不会打开.)您只能在使用此设置之前获取连接.
但是,您可以避免弄乱内部并仍然获得所有这些好处.就个人而言,我创建了自己的小全局方法:
import flask
import sqlite3
def request_has_connection():
return hasattr(flask.g, 'dbconn')
def get_request_connection():
if not request_has_connection():
flask.g.dbconn = sqlite3.connect(DATABASE)
# Do something to make this connection transactional.
# I'm not familiar enough with SQLite to know what that is.
return flask.g.dbconn
@app.teardown_request
def close_db_connection(ex):
if request_has_connection():
conn = get_request_connection()
# Rollback
# Alternatively, you could automatically commit if ex is None
# and rollback otherwise, but I question the wisdom
# of automatically committing.
conn.close()
Run Code Online (Sandbox Code Playgroud)
然后,在整个应用程序中,始终通过get_request_connection您的get_db功能获取您的连接.直截了当,效率高.基本上,两全其美.
回想起来,我真的不喜欢这些是全局方法的事实,但我认为它的原因是因为这就是Flask的工作原理:它为你提供了实际指向线程本地的"全局".
我推荐使用Flask-SQLAlchemy,它扩展了SQLAlchemy以便在Flask中使用,因此它支持许多不同的数据库.(来自Flask-SQLAlchemy文档的示例)
建立:
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
def __init__(self, username, email):
self.username = username
self.email = email
def __repr__(self):
return '<User %r>' % self.username
Run Code Online (Sandbox Code Playgroud)
现在,您只需导入/使用User该类即可访问数据库中的User表.
创建新用户:
>>> from yourapplication import User
>>> admin = User('admin', 'admin@example.com')
>>> guest = User('guest', 'guest@example.com')
Run Code Online (Sandbox Code Playgroud)
将用户添加到数据库:
>>> db.session.add(admin)
>>> db.session.add(guest)
>>> db.session.commit()
Run Code Online (Sandbox Code Playgroud)
查询已存在于数据库中的用户:
>>> users = User.query.all()
[<User u'admin'>, <User u'guest'>]
>>> admin = User.query.filter_by(username='admin').first()
<User u'admin'>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
40396 次 |
| 最近记录: |