내 응용 프로그램을 실행하는 데 어려움을 겪고 있습니다. Flask-SQLAlchemy 확장은 패키지에서 모듈을 분리하려고 할 때마다 빈 데이터베이스를 만듭니다. 내가하는 일을 더 잘 설명하기 위해 프로젝트가 어떻게 구성되어 있는지 보여 드리겠습니다.
Project
|
|-- Model
| |-- __init__.py
| |-- User.py
|
|-- Server
| |-- __init__.py
|
|-- API
| |-- __init__.py
아이디어는 간단합니다. 단일 패키지로 코드를 퍼뜨리는 것을 좋아하지 않기 때문에 모델 용 패키지를 만들고 앞으로는 블루 프린트를 사용하여 더 나아질 것이므로 별도의 "하위"프로젝트 (예 : API)를 만들고 싶습니다. 하위 앱을 분리합니다.
코드는 매우 간단합니다.
첫째, Model.__init__.py
:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
SQLAlchemy()
패키지 전체에 단일 객체 를 사용하기 위해서만 이것을 만들었습니다 . 아니요, Model.User로 이동합니다.
from Model import db
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
Name = db.Column(db.String(80))
Age = db.Column(db.Integer)
...
동일한 db 개체를 허용하는 데 사용한 from Model import db를 다시 한 번 확인합니다.
마지막으로 다음과 같이 Server.__init__.py
진행됩니다.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import Model, API
db = Model.db
def main():
app = Flask("__main__")
db = SQLAlchemy(app)
db.create_all()
API.SetAPIHookers(app)
app.run(host="0.0.0.0", port=5000, debug=True)
if __name__ == "__main__":
main()
내 관점에서 보면 db = SQLAlchemy(app)
순환 참조를 만들지 않고도 앱 개체를 전달할 수 있습니다.
문제는이 코드를 실행할 때마다 sqlite 데이터베이스 파일이 비어 있다는 것입니다. 그것은 아마도 파이썬이 내가 생각했던 것과 같은 것을 가져 오지 않는다고 생각하게 만들었다. 그래서 가져 오기 모델을 제거하고 서버 내부에서 직접 사용자를 생성하여 내 이론을 테스트했습니다.
이제 내 질문이 온다 : 내가 원하는대로 모듈을 올바르게 분리하는 '파이썬'방법이 있습니까 아니면 모든 것을 동일한 패키지에 두어야합니까?
지금은 " Application Factory "패턴 (Flask 문서에서 불림) 과 대략적으로 동등한 것을 사용하여 애플리케이션을 설정했습니다 . 이것은 Python 아이디어가 아니라 Flask 아이디어입니다. 몇 가지 장점이 있지만 init_app
SQLAlchemy 생성자가 아닌 메서드를 사용하여 SQLAlchemy 개체를 초기화하는 등의 작업을 수행해야 함을 의미하기도합니다 . 이 방법으로 "잘못된"것은 없지만 응용 프로그램 컨텍스트create_all()
내에서 와 같은 메서드를 실행해야 함을 의미합니다. 현재는 메서드 에서 실행하려고하면 그렇지 않습니다 .main()
이 문제를 해결할 수있는 몇 가지 방법이 있지만 원하는 방법을 결정하는 것은 귀하에게 달려 있습니다 (정답 없음).
이런 식으로 함수에서 앱을 만들지 않습니다. 대신 어딘가에 배치합니다 (예 :) project/__init__.py
. 귀하의 project/__init__.py
파일을 가져올 수 있습니다 models
그동안, 패키지를 models
패키지를 가져올 수 있습니다 app
에서 project
. 이것은 순환 참조이지만 에서 가져 오기 를 시도하기 전에 먼저 패키지 app
에서 객체를 생성 하는 한 괜찮 습니다 . 패키지를 여러 패키지로 분할 할 수 있지만 이러한 다른 패키지가 순환 참조 를 사용하여 객체 를 사용할 수 있도록하는 예 는 더 큰 애플리케이션 패턴에 대한 Flask 문서를 참조하세요. 문서는 심지어 다음과 같이 말합니다.project
model
app
package
app
모든 파이썬 프로그래머는 그것들을 싫어하지만 우리는 순환 가져 오기를 추가했습니다. [...] 이것은 일반적으로 나쁜 생각이지만 여기에서는 실제로 괜찮습니다.
이렇게하면 생성자에서 앱에 대한 참조를 Models/__init__.py
사용하여 SQLAlchemy
개체 를 빌드하도록 파일을 변경할 수 있습니다 . 이러한 방식으로 Flask-SQLAlchemy 설명서에 설명 된대로 개체 의 create_all()
및 drop_all()
메서드를 사용할 수 있습니다 .SQLAlchemy
지금 가지고있는 작업을 계속하면 (함수에서 앱 만들기), 생성자의 일부로 개체를 사용하지 않고 패키지 에서 SQLAlchemy
개체 를 빌드해야합니다 (완료 한대로). 주요 방법에서 변경 ...Models
app
db = SQLAlchemy(app)
...에게 ...
db.init_app(app)
그런 다음 create_all()
메서드를 애플리케이션 컨텍스트 내부의 함수로 이동해야합니다 . 프로젝트 초기에 이것을 수행하는 일반적인 방법은 before_first_request()
데코레이터 를 활용하는 것입니다 ....
app = Flask(...)
@app.before_first_request
def initialize_database():
db.create_all()
"initialize_database"메소드는 첫 번째 요청이 Flask에서 처리되기 전에 실행됩니다. 다음 app_context()
방법 을 사용하여 언제든지이 작업을 수행 할 수도 있습니다 .
app = Flask(...)
with app.app_context():
# This should work because we are in an app context.
db.create_all()
애플리케이션 팩토리 패턴을 계속 사용하려면 애플리케이션 컨텍스트가 작동하는 방식을 실제로 이해해야합니다. 처음에는 혼란 스러울 수 있지만 "응용 프로그램이 db 인스턴스에 등록되지 않았고 현재 컨텍스트에 바인딩 된 응용 프로그램이 없습니다"와 같은 오류가 무엇을 의미하는지 알아야합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다