2013-11-04 11 views
6

पृष्ठभूमि: बोतल/कुप्पी के SQLAlchemy/कुप्पी के WTF, कथात्मक और सत्र scoped का उपयोग करSQLAlchemy सत्र त्रुटि

सरल POST आपरेशन:

:

@tas.route('/order_add', methods=['GET', 'POST']) 
def tas_order_add(): 
    if request.method == 'POST': 
     order_form = OrderForm() 
     if order_form.validate_on_submit(): 
      order = Order() 
      order_form.populate_obj(order) 
      db_session.add(order) 
      db_session.commit() 

अब इसे चलाने के लिए मैं कोई त्रुटि मिलती है की कोशिश कर रहा

InvalidRequestError: Object '' is already attached to session '1' (this is '2')

विलय करने के लिए जोड़ने के बदलने से समस्या का हल है, लेकिन:

  • मैं कारण है कि मैं एक वस्तु मर्ज करने के लिए है, जबकि मैं सिर्फ यह
  • मैं बदल विलय और लाइन में गुण कुछ में से एक परिभाषित करने की कोशिश करने के लिए जोड़ रहे हैं तो शुरू की कर पता नहीं है

    order = Order() 
    order_form.populate_obj(order) 
    order.order_status = OrderStatus.query.filter(OrderStatus.code=='PLACED').first() 
    db_session.merge(order) 
    db_session.commit() 
    

    मैं

    InvalidRequestError: Object '' is already attached to session '2' (this is '1')

कोई मुझे बात कर सकते हैं जहां मैंने कुछ गलत कर रहा हूँ क्योंकि यह मुझे पागल गाड़ी चला रहा है OrderStatus वस्तु पर एक ही त्रुटि मिलती है, बस अब। मुझे स्क्लेक्लेमी के साथ कुछ अनुभव है लेकिन यह पहली बार है जब मैं ऐसा व्यवहार देखता हूं और मैं समस्या को इंगित नहीं कर सकता।

मुझे मिला सभी खोजना डबल डेटाबेस सत्र प्रारंभिक समस्या के साथ एक समस्या थी, लेकिन मैं इस मामले को विश्वास नहीं करता हूं।

संपादित

db_session सामग्री

from sqlalchemy.engine import create_engine 
from sqlalchemy.ext.declarative.api import declarative_base 
from sqlalchemy.orm.scoping import scoped_session 
from sqlalchemy.orm.session import sessionmaker 

engine = create_engine('sqlite:///fundmanager_devel.db', convert_unicode=True) 
db_session = scoped_session(sessionmaker(autocommit=False, 
             autoflush=False, 
             bind=engine)) 
Base = declarative_base() 
Base.query = db_session.query_property() 
+0

जहां db_session परिभाषित किया गया है? क्या आप इसके लिए कोड जोड़ सकते हैं? –

+0

प्रश्न –

उत्तर

4

कि अजीब है निम्नलिखित के साथ अलग फाइल database.py में परिभाषित किया गया है। यदि आप फ्लास्क-स्क्लेल्चेमी का उपयोग कर रहे हैं तो आप इंजन और घोषणात्मक आधार को स्पष्ट रूप से क्यों बना रहे हैं? यह संभावना है कि आपकी समस्या कहां है। ऐसा लगता है कि आपके पास दो इंजन और सत्र एक साथ चल रहे हैं, यही कारण है कि आपको त्रुटि मिली है।

इसके बजाय इंजन स्पष्ट रूप से बनाने के बजाय, आप बस का उपयोग करना चाहिए:

from flask.ext.sqlalchemy import SQLAlchemy 

db = SQLAlchemy() 

और अपने अनुप्रयोग फैक्ट्री के अंदर:

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///fundmanager_devel.db' 
db.init_app(app) 

फिर अपने आधार कथात्मक मॉडल db.Model है, आपका सत्र db.session में है, और आपको फ्लास्क अनुरोध संदर्भ सत्र निर्माण का प्रबंधन करना चाहिए।

चेक कुप्पी के SQLAlchemy डॉक्स में कम से कम आवेदन उदाहरण:

Most web frameworks include infrastructure to establish a single Session, associated with the request, which is correctly constructed and torn down corresponding torn down at the end of a request. Such infrastructure pieces include products such as Flask-SQLAlchemy, for usage in conjunction with the Flask web framework, and Zope-SQLAlchemy, for usage in conjunction with the Pyramid and Zope frameworks. SQLAlchemy strongly recommends that these products be used as available.

http://docs.sqlalchemy.org/en/rel_0_9/orm/session.html

+0

पर एक संपादन के रूप में जोड़ा गया है मैंने कुछ दस्तावेज़ पढ़े हैं, जिस तरह से इसे परिभाषित किया जाना चाहिए। मेरे पास सेटअप के साथ एक चल रहा एप्लिकेशन है और इससे कोई समस्या नहीं आई है। मैं आपकी सलाह लेता हूं और अपना सेटअप बदलता हूं और –

+0

की रिपोर्ट करता हूं, इस तरह आप इसे फ्लास्क के बिना एक स्क्लेक्लेमी एप्लिकेशन पर उपयोग करते हैं। यदि आप फ्लास्क, या अन्य ढांचे का उपयोग कर रहे हैं, तो आपको एक ही सत्र के आसपास गारंटी देने के लिए प्रदत्त आधारभूत संरचना का उपयोग करना चाहिए। मैंने इस बिंदु का उल्लेख करते हुए SQLAlchemy दस्तावेज़ जोड़ने के लिए अपना जवाब संपादित किया। –

+0

शायद यह मेरी समस्या नहीं है। मैंने अपने ऐप को घोषणात्मक का उपयोग न करने के लिए बदल दिया है, लेकिन समस्या बनी हुई है। मुझे संदेह है कि यह एक बात है कि डीबी प्रारंभिकता के साथ मेरा init दो बार चलाया जाता है (इसे प्रिंट डीबग के साथ चेक किया जाता है) और दो बार डीबी कनेक्शन बनाता है। मुझे समस्या नहीं मिल रही है, मैंने ट्यूटोरियल के साथ ऐप सेटअप किया है। यह वास्तव में कुछ बेवकूफ होना चाहिए लेकिन मुझे बस यह नहीं मिल रहा है। –

5

सत्र मिश्रण के साथ एक समस्या लगता है:

http://pythonhosted.org/Flask-SQLAlchemy/quickstart.html#a-minimal-application

यह है कि यह कैसे SQLAlchemy द्वारा सिफारिश की है ऊपर, मैंने इसे निम्नानुसार उपयोग किया और यह काम करता है:

forms.py:

class SurgeryForm(Form): 
    study = QuerySelectField('Study', 
          query_factory=StudyGroup.query.all, 
          get_label='name') 

models.py

class Animal(db.Model): 
    study_id = db.Column(db.Integer, db.ForeignKey('study_group.id')) 

class StudyGroup(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(50)) 
    animals = db.relationship('Animal', backref='group', lazy='dynamic') 

views.py:

def do_surgery(): 
    form = SurgeryForm(request.form) 

    if form.validate_on_submit(): 
     a = models.Animal() 
     form.populate_obj(a) # Gather the easy stuff automagically 
     #a.group = form.data['study'] #FAILS! 
     a.study_id = form.data['study'].id #WORKS! 
from <project> import db 
from <project.models import Category 

category = QuerySelectField('category', query_factory=lambda: db.session.query(Category), get_pk=lambda a: a.id, get_label=lambda a: a.name) 
+0

'category.query.all() 'के बजाय' db.session.query (श्रेणी)' का उपयोग करके मेरे लिए काम किया। धन्यवाद! –

5

मैं QuerySelectField के साथ एक समान समस्या थी ऐसा लगता है SQLAlchemy (या संभवतः फ्लास्क-स्क्लाक्लेमी या फ्लास्क-डब्ल्यूटीएफ) नई पशु वस्तु बनाने के लिए QuerySelectField और किसी अन्य सत्र में मान एकत्र करने के लिए एक सत्र का उपयोग करता है।

यदि आप backref (Animal.group) का उपयोग करके AnimalGroup ऑब्जेक्ट को पशु में संलग्न करने का प्रयास करते हैं तो आप इस समस्या में भाग लेंगे (क्योंकि विभिन्न सत्रों से जुड़े ऑब्जेक्ट्स)। मैं जिस कामकाज का उपयोग कर रहा हूं वह विदेशी कुंजी (Animal.study_id) को सीधे सेट करना है।

स्पष्ट रूप से मैं इस जवाब के साथ पार्टी के लिए थोड़ा देर हो चुकी हूं, लेकिन मुझे आशा है कि यह किसी की मदद करेगी!

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