Flask에서 데이터베이스에 연결하면 어떤 접근 방식이 더 낫습니까?
방법 1 : 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()
방법 2 : 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()
어떤 방법이 더 낫습니까? 차이점은 무엇입니까?
둘 사이의 차이점은 방법 1은 g.db
필요 여부에 대한 연결을 생성하는 반면 방법 2 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)
setup ( )을 /
사용하여 눌렀을 때 사용 여부 에 관계 없이 연결 되는 것을 볼 수 있으며 , 경로를 사용 하면 전화를 걸 때만 연결 됩니다 .@app.before_request
g.db
_app_context
get_db
공정 g
하게 말하면 동일한 지연 연결 (또는 실제 연결 풀에서 연결 획득)을 수행 할 설명자를 추가 할 수도 있습니다 . 그리고에 둘 경우 당신은 (좀 더 마법을 사용할 수 werkzeug.local.LocalProxy
정확합니다) 사용자 정의 만들려면 현지 스레드를 같은 역할을하는 g
, current_app
그리고 request
( 다른 사람의 사이에서 ).
첫 번째는 필요하지 않은 경우에도 연결을 확보하는 문제입니다. 두 번째는 써드 파티 프레임 워크의 내부를 가지고 노는 단점이 있으며 읽기도 꽤 어렵습니다.
둘 중 두 번째가 더 나은 선택 일 것입니다. 필요하지 않은 경로에 대한 연결을 획득하지 않을뿐만 아니라 경로의 다른 코드 경로에 연결이 필요하더라도 연결이 필요하지 않은 코드 경로로 이동하면 연결을 획득하지 않습니다. (예를 들어, 일부 양식 유효성 검사가있는 경우 유효성 검사에 통과 한 경우에만 연결이 필요합니다. 유효성 검사가 실패하면 연결이 열리지 않습니다.)이 설정에서 연결을 사용하기 직전에 연결 만 획득합니다.
그러나 내부 문제를 피하고 이러한 모든 이점을 얻을 수 있습니다. 개인적으로 저는 저만의 작은 전역 메서드를 만들었습니다.
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()
Then, throughout the app, always get your connection via get_request_connection
, just as you would your get_db
function. Straightforward and high efficiency. Basically, the best of both worlds.
Edit:
In retrospect, I really dislike the fact these are global methods, but I think the reason for it is because that's how Flask works: it gives you "globals" that actually point to thread-locals.
I recommend Flask-SQLAlchemy, which extends SQLAlchemy for use in Flask, so it supports many different databases. (Example from Flask-SQLAlchemy documentation)
Setup:
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
Now, you can just import/use the User
class to access the User table in your database.
Create new users:
>>> from yourapplication import User
>>> admin = User('admin', 'admin@example.com')
>>> guest = User('guest', 'guest@example.com')
Add the users to the database:
>>> db.session.add(admin)
>>> db.session.add(guest)
>>> db.session.commit()
Query for users already in database:
>>> users = User.query.all()
[<User u'admin'>, <User u'guest'>]
>>> admin = User.query.filter_by(username='admin').first()
<User u'admin'>
I'd go with method one - more readable and less "hackish".
The method 2 is probably designed for flask extensions integration (example and explanation of app-ctx-stack). Although they probably have very similar effect, method one should be used for normal cases.
ReferenceURL : https://stackoverflow.com/questions/16311974/connect-to-a-database-in-flask-which-approach-is-better
'Programing' 카테고리의 다른 글
유니 코드 what ()의 예외 (0) | 2020.12.31 |
---|---|
python-matplotlib에서 3D 다각형 플로팅 (0) | 2020.12.31 |
Xcode 7 : 저장소에서 .xcscmblueprint를 무시 하시겠습니까? (0) | 2020.12.31 |
암호화 된 보안 인증 토큰 생성 (0) | 2020.12.31 |
HTML 콘텐츠가 포함 된 contentEditable 영역에서 캐럿 (커서) 위치 가져 오기 (0) | 2020.12.31 |