flask app에서 sqlalchemy를 사용할지, flask-sqlalchemy를 사용할지 고민하고 사용법을 알아보며 필요한 내용을 정리했다.
flask-sqlalchemy vs sqlalchemy
flask Blueprint
- flask는 application components를 만들고, application 내부 혹은 application 여러 개에서 공통되는 패턴을 적용하기 위해 사용된다.
- Blueprints를 사용하는 경우
- 큰 application을 blueprint의 집합으로 구성
- blueprint를 application의 prefix나 subdomain으로 등록
- 하나의 blueprint를 서로 다른 URL 규칙을 가진 application에 여러 번 등록
- template, static file 등을 여러 blueprint에 공통적으로 제공
- Blueprint는 app이 아니라, application에 여러번도 등록될 수 있는 operation의 집합이다.
- Blueprint를 이용하는 대신 여러 개의 application을 사용할 수 있지만, 그 경우 각 application에 대한 config가 별도로 필요하며, 이것들은 WSGI layer에서 관리되어야 한다.
- Blueprint는 Flask level의 분리를 지원하며, application config를 공유하고 필요한 경우 다른 application 객체에 등록될 수도 있다.
- 참고
flask application context
- flask app을 여러개 만들거나, 특정 함수 안에서 dynamic하게 app을 만들고 싶을 때 사용한다. 함수 안에서 app을 만들고, SQLAlchemy 객체는 global scope에서 만들었을 때 SQLAlchemy 객체는 어떻게 app 에 대해 알 수 있을까? 이 때 init_app() 함수를 사용해 SQLAlchemy 객체를 초기화해야 한다.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
db.init_app(app)
return app
- 위 코드는 application 이 SQLAlchemy와 같이 동작할 수 있는 준비를 하도록 하지만, 두 가지가 바로 bind되는것은 아니다.
- SQLAlchemy가 application에 대해서 알려면 application context를 이용해야 한다.
- application context 바깥에서 db를 다루려고 하는 경우, 다음과 같은 에러 메세지를 볼 수 있다.
No application found. Either work inside a view function or push an application context.
- application context는 다음과 같은 방식으로 사용한다.
def my_function():
with app.app_context():
user = db.User(...)
db.session.add(user)
db.session.commit()
paginate
- Basequery.paginate()는 flask-sqlalchemy의 어느 query 객체에서나 호출될 수 있다.
- arguments
- page number: 1부터 시작
- page 당 item 수
- error flag: True인 경우 out of range page가 요청되면 404 에러를 자동으로 반환한다. False인 경우 빈 list가 반환된다.
- return
- paginate는 Pagination object를 반환한다. 이 객체의 item 속성은 결과의 list를 반환한다.
참고