python - फ्लास्क-स्क्लाक्लेमी आयात/संदर्भ समस्या




flask flask-sqlalchemy (2)

मैं अपने फ्लास्क ऐप को कुछ इस प्रकार बनाना चाहता हूं:

./site.py
./apps/members/__init__.py
./apps/members/models.py

apps.members एक फ्लास्क ब्लूप्रिंट है।

अब, मॉडल कक्षाएं बनाने के लिए मुझे ऐप को पकड़ने की आवश्यकता है, जैसे कुछ:

# apps.members.models
from flask import current_app
from flaskext.sqlalchemy import SQLAlchemy

db = SQLAlchemy(current_app)

class Member(db.Model):
    # fields here
    pass

लेकिन अगर मैं अपने ब्लूप्रिंट ऐप में उस मॉडल को आज़माकर आयात करता हूं, तो मुझे RuntimeError: working outside of request context त्रुटि मिलती है RuntimeError: working outside of request context । मैं यहां अपने ऐप को सही तरीके से कैसे पकड़ सकता हूं? सापेक्ष आयात काम कर सकते हैं लेकिन वे बहुत बदसूरत हैं और उनके अपने संदर्भ मुद्दे हैं, उदाहरण के लिए:

from ...site import app

# ValueError: Attempted relative import beyond toplevel package

एक मूल app.py : http://pythonhosted.org/Flask-SQLAlchemy/quickstart.html#quickstart

...

app = flask.Flask(__name__)
app.config['DEBUG'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = flask.ext.sqlalchemy.SQLAlchemy(app)

class Person(db.Model):
    id = db.Column(db.Integer, primary_key=True)
...

class Computer(db.Model):
    id = db.Column(db.Integer, primary_key=True)
...

# Create the database tables.
db.create_all()

...

# start the flask loop
app.run()

मैंने Blueprint का उपयोग किए बिना app.py और model.py में एक app.py को विभाजित किया। उस स्थिति में, उपर्युक्त उत्तर काम नहीं कर रहा है। काम करने के लिए एक लाइन कोड की आवश्यकता है।

इससे पहले :

db.init_app(app)

के बाद :

db.app = app
db.init_app(app)

और, निम्न लिंक बहुत उपयोगी है।

http://piotr.banaszkiewicz.org/blog/2012/06/29/flask-sqlalchemy-init_app/


flask_sqlalchemy मॉड्यूल को तुरंत ऐप के साथ प्रारंभ करने की आवश्यकता नहीं है - आप इसे इसके बजाय कर सकते हैं:

# apps.members.models
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class Member(db.Model):
    # fields here
    pass

और फिर अपने एप्लिकेशन सेटअप में आप init_app को कॉल कर सकते हैं:

# apps.application.py
from flask import Flask
from apps.members.models import db

app = Flask(__name__)
# later on
db.init_app(app)

इस तरह आप चक्रीय आयात से बच सकते हैं।

इस पैटर्न को आपके सभी मॉडलों को एक फ़ाइल में रखने की आवश्यकता नहीं है। बस अपने प्रत्येक मॉडल मॉड्यूल में db वैरिएबल आयात करें।

उदाहरण

# apps.shared.models
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

# apps.members.models
from apps.shared.models import db

class Member(db.Model):
    # TODO: Implement this.
    pass

# apps.reporting.members
from flask import render_template
from apps.members.models import Member

def report_on_members():
    # TODO: Actually use arguments
    members = Member.filter(1==1).all()
    return render_template("report.html", members=members)

# apps.reporting.routes
from flask import Blueprint
from apps.reporting.members import report_on_members

reporting = Blueprint("reporting", __name__)

reporting.route("/member-report", methods=["GET","POST"])(report_on_members)

# apps.application
from flask import Flask
from apps.shared import db
from apps.reporting.routes import reporting

app = Flask(__name__)
db.init_app(app)
app.register_blueprint(reporting)

नोट: यह कुछ शक्तियों का एक स्केच है जो आपको देता है - जाहिर है कि विकास को और भी आसान बनाने के लिए आप कुछ और कर सकते हैं (एक create_app पैटर्न का उपयोग करके, कुछ फ़ोल्डरों में स्वत: पंजीकरण ब्लूप्रिंट आदि)





flask-sqlalchemy