2013-10-17 5 views
53

मैं कर रहा हूँ मेरी बोतल आवेदन मॉडल, ब्लूप्रिंट बिखरने द्वारा फिर से बाँटे लेकिन मैं एक रनटाइम त्रुटि हो रहा है उठाया गया था।बोतल मॉडल बिखरने, RuntimeError जब: 'आवेदन db पर पंजीकृत नहीं'

def create_app(): 
    app = flask.Flask("app") 
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://' 
    app.register_blueprint(api) 
    db.init_app(app) 
    db.create_all() 
    return app 

मैं निम्नलिखित समस्या (नमूना परियोजना यहाँ की मेजबानी कर रहे हैं: https://github.com/chfw/sample): है

Traceback (most recent call last): 
    File "application.py", line 17, in <module> 
    app = create_app() 
    File "application.py", line 12, in create_app 
    db.create_all() 
    File "\AppData\Roaming\Python\Python27\site-packages\flask_sqlalchemy\__init__.py", line 856, in create_all 
    self._execute_for_all_tables(app, bind, 'create_all') 
    File "\AppData\Roaming\Python\Python27\site-packages\flask_sqlalchemy\__init__.py", line 836, in _execute_for_all_tables 
    app = self.get_app(app) 
    File "\AppData\Roaming\Python\Python27\site-packages\flask_sqlalchemy\__init__.py", line 809, in get_app 
    raise RuntimeError('application not registered on db 
      'RuntimeError: application not registered on db 
      instance and no application bound to current context 

मैं इस विषय पर एक शोध किया। फिर से फैक्टरिंग यहाँ का सुझाव दिया है:

Flask-SQLAlchemy import/context issue

एक ही समस्या यहाँ उठाया गया था:

app.register_blueprint(api) 
    db.app=app #<------------<< 
    db.init_app(app) 
:

http://flask.pocoo.org/mailinglist/archive/2010/8/30/sqlalchemy-init-app-problem/#b1c3beb68573efef4d6e571ebc68fa0b

और ऊपर धागा (2010) इस तरह एक हैक सुझाव

क्या किसी को यह ठीक से कैसे करना है? आपने इसे कैसे ठीक किया?

धन्यवाद

उत्तर

121

यह बोतल के application context से कोई लेना देना नहीं है। db.init_app(app) के साथ प्रारंभ होने पर, फ्लास्क-स्क्लाक्लेमी को पता नहीं है कि कौन सा ऐप "चालू" ऐप है (याद रखें, फ्लास्क उसी दुभाषिया में multiple apps के लिए अनुमति देता है)। आप एक ही प्रक्रिया में एक ही SQLAlchemy उदाहरण का उपयोग कर कई क्षुधा हो सकता था, और कुप्पी के SQLAlchemy पता करने के लिए जो "वर्तमान" एक (बोतल के सब कुछ के context local प्रकृति के कारण) है की आवश्यकता होगी।

आप रनटाइम के दौरान ऐसा करने की जरूरत है, तो आप स्पष्ट रूप से कहना होगा जो एप्लिकेशन को सभी कॉल के लिए "वर्तमान" एप्लिकेशन है।

def create_app(): 
    app = flask.Flask("app") 
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://' 
    app.register_blueprint(api) 
    db.init_app(app) 
    with app.app_context(): 
     # Extensions like Flask-SQLAlchemy now know what the "current" app 
     # is while within this block. Therefore, you can now run........ 
     db.create_all() 

    return app 

आप एक स्टैंडअलोन स्क्रिप्ट एप्लिकेशन संदर्भ की जरूरत है लिख रहे हैं, तो आप शुरुआत के बजाय में सब कुछ डाल पर संदर्भ धक्का कर सकते हैं: आप एक with app.app_context() ब्लॉक का उपयोग करने के लिए अपने कोड को बदलने के द्वारा यह कर सकता हूँ एक with ब्लॉक।

create_app().app_context().push() 

आप बोतल के cli के लिए एक कमांड लिखते हैं तो आदेश स्वचालित रूप से संदर्भ के लिए उपयोग होगा।

+0

ठीक है, यह काम करता है। अब मुझे अपवाद नहीं मिलते हैं। लेकिन अगला वाला यह है: "एप्लिकेशन डीबी पर पंजीकृत नहीं है" -> रनटाइम त्रुटि: एप्लिकेशन डीबी इंस्टेंस पर पंजीकृत नहीं है और वर्तमान संदर्भ – chfw

+2

पर कोई एप्लिकेशन बाध्य नहीं है और यहां अंतर क्या है और db.app = ऐप जोड़ रहा है? – user805981

+1

@ user805981 इस तरह से काम कर सकता है, लेकिन यह बहुत साफ नहीं है। सबसे पहले, आप encapsulation तोड़ रहे हैं, क्योंकि SQLAlchemy पर 'ऐप' विशेषता सार्वजनिक होने के लिए डिज़ाइन नहीं की गई है। उस ऑब्जेक्ट को अन्य चीजों को करने की आवश्यकता हो सकती है जब यह बदल रहा है कि यह किस ऐप का उपयोग कर रहा है। दूसरा, 'app_context' केवल फ्लास्क-स्क्लाक्लेमी को बदलने से अधिक करता है; यह वास्तव में वर्तमान ऐप को बदलने के लिए फ्लास्क को बताता है। इस प्रकार, आपको विभिन्न फ्लास्क एपीआई के साथ चीजों को करने की आवश्यकता हो सकती है, या अपने सभी अन्य फ्लास्क एक्सटेंशन के साथ ऐप के साथ काम करने की आवश्यकता हो सकती है। –

5

मार्क जवाब महान था और यह मुझे बहुत मदद की। हालांकि, इसका दृष्टिकोण करने का एक और तरीका है कोड को चलाने के लिए जो ऐप संदर्भ पर निर्भर करता है @ app.before_first_request से सजाए गए फ़ंक्शन में। अधिक जानकारी के लिए http://flask.pocoo.org/docs/0.10/appcontext/ देखें। वास्तव में मैं इसे कैसे कर रहा हूं, काफी हद तक क्योंकि मैं फ्लास्क के बाहर प्रारंभिक कोड को कॉल करने में सक्षम होना चाहता था, जिसे मैं इस तरह से संभालता हूं।

मेरे मामले में मैं स्क्वाक्लेमी मॉडल को फ्लास्क-स्क्लाक्लेमी के बिना सादे स्क्लाक्लेमी मॉडल के रूप में परीक्षण करने में सक्षम होना चाहता हूं, हालांकि नीचे दिए गए कोड में डीबी बस एक (फ्लास्क) SQLAlchemy डीबी है।

@app.before_first_request 
def recreate_test_databases(engine = None, session = None): 
    if engine == None: 
    engine = db.engine 
    if session == None: 
    session = db.session 

    Base.metadata.drop_all(bind=engine) 
    Base.metadata.create_all(bind=engine) 
    # Additional setup code 
+0

जॉन काम करता है, क्या आप इस में डुप्लिकेट उत्तर मर्ज कर सकते हैं (चूंकि इस में अपवॉट है) और दूसरे को हटा दें? – KobeJohn

+0

हटाया गया, कोई मर्ज आवश्यक नहीं है। –

+0

किसी फ़ाइल के लिए कोई सुझाव जो '@ app.before_first_request' फ़ंक्शंस रखना चाहिए? – AlexLordThorsen

संबंधित मुद्दे