ফ্লাস্ক-এসকিউএএচএলএলচেমি আমদানি / প্রসঙ্গ ইস্যু


117

আমি আমার ফ্লাস্ক অ্যাপটিকে এমন কিছু কাঠামো করতে চাই:

./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। আমি কীভাবে এখানে আমার অ্যাপ্লিকেশনটিকে সঠিকভাবে ধরে রাখতে পারি? আপেক্ষিক আমদানিগুলি কাজ করতে পারে তবে তারা বেশ কুৎসিত এবং তাদের নিজস্ব প্রসঙ্গ সমস্যা রয়েছে, যেমন:

from ...site import app

# ValueError: Attempted relative import beyond toplevel package

উত্তর:


294

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প্যাটার্ন ব্যবহার করে, নির্দিষ্ট ফোল্ডারে ব্লুপ্রিন্টগুলি স্বয়ংক্রিয়ভাবে নিবন্ধকরণ ইত্যাদি)


2
আপনি কি একাধিক বার করতে পারেন? উদাহরণস্বরূপ যদি আমার কাছে একাধিক মডেল.পি ফাইল থাকে?
ব্র্যাড রাইট

@ ব্র্যাড রাইট - আপনি যদি আপনার dbপ্রতিটি ডাটাবেসের জন্য কেবল উদাহরণ তৈরি করেন তবে এটি সহজ করে তোলে । আপনার কাছে যদি মডেলগুলির একটি প্যাকেজ থাকে তবে আপনি এটি লাগাতে পারেন __init__.py। তবে আপনি এটি করতে বেছে নিলে, আপনি কেবল dbসেই অবস্থান থেকে আপনার অন্যান্য মডেল ফাইলগুলিতে ভেরিয়েবলটি আমদানি করেন এবং এটিকে স্বাভাবিক হিসাবে ব্যবহার করেন। যখন এগুলি লোড করা হয় তখন সমস্ত কিছু সঠিকভাবে সমাধান হয়।
শান ভিয়ারা

1
আপনি কি এমনভাবে কোনও প্রকল্পের জন্য একটি লিঙ্ক স্থাপন করবেন?
এমব্রেভদা

4
@ এমব্রেভদা - আপনি এখানে এই প্যাটার্নের একটি উদাহরণ দেখতে পাচ্ছেন github.com/svieira/Budget-Manager
শান

1
.ext.নামস্থান অবচিত - এটা বাস্তব নামস্থান থেকে আমদানি ভালো ( flask_sqlalchemy)।
শান ভিয়েরা

25

একটি আসল অ্যাপ.পি : https : //flask-sqlalchemy.palletspro پروژې.com / en / 2.x / 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()

আমি ব্লুপ্রিন্ট ব্যবহার না করেই একটি app.py কে app.py এবং Model.py এ বিভক্ত করেছি। সেক্ষেত্রে উপরের উত্তরগুলি কাজ করে না। কাজ করার জন্য একটি লাইন কোড প্রয়োজন।

আগে :

db.init_app(app)

পরে :

db.app = app
db.init_app(app)

এবং, নিম্নলিখিত লিঙ্কটি খুব দরকারী is

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


2
db.app = appরানটাইমার হচ্ছিল কারণ init_app অ্যাপটি সেট করে না। +1
অমিত ত্রিপাঠি

3
db.app = app(তারপরে db.init_app(app)) আমার জন্য অনুপস্থিত অংশ ছিল। সেই লাইনটি যুক্ত করার পরে পুরোপুরি কাজ করে (শান
ভাইয়েরার

প্রথম লিঙ্কটি পুরানো।
রাহুল কেপি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.