2016-06-07 5 views
0

ich die folgende Passage von Code verwenden:sqlalchemy nicht Objekt Änderungen an Postgres DB begeht

@app.route('/budget_item/<int:budget_id>/edit', methods=['GET', 'POST']) 
    def budget_item_edit(budget_id): 


budget_item = session.query(Budget).filter_by(id=budget_id).one() 
print "Start EDIT sequence" 


# Return form data from HTML initial load form 
elif request.method == 'POST': 

    budget_amount_reallocated_total = budget_item.budget_amount_reallocated_total 


    #ORIGINAL BUDGET 
    if request.form['transaction_type'] == 'Original Budget': 

    #amount 
    if request.form['amount'] == "": 
     amount = 0 
    else: 
     amount = float(str(request.form['amount'])) 

    budget_item = Budget(
     #created_date = "", 
     budget_transaction_type = request.form['transaction_type'], 
     budget_line = request.form['budget_line'], 
     amount = amount, 
     description = request.form['description'] 
     #date_received = request.form['date_received'] 
    ) 

    try: 
     count = 1 

     while count < 10000: 
     count += 1 

     #budget_line 
     setattr(budget_item,'budget_line'+str(count),request.form['budget_line'+str(count)]) 

     #amount 
     setattr(budget_item,'amount'+str(count),float(request.form['amount'+str(count)])) 
     budget_amount_reallocated_total += float(request.form['amount'+str(count)]) 
     setattr(budget_item, 'budget_amount_reallocated_total', budget_amount_reallocated_total) 

     #description 
     setattr(budget_item,'description'+str(count), request.form['description'+str(count)]) 

     #date_received 
     setattr(budget_item,'date_received'+str(count),request.form['date_received'+str(count)]) 
     session.commit() 

    except: 
     session.commit() 
     return redirect(url_for('budget_master')) 

    else: 
    print "I'm done! This is not a post request" 

Dieser Codeblock ist Setup-Daten von einer HTML über eine POST-Anforderung übergibt ein dann ein entsprechendes Objekt aktualisieren in die Postgres-Datenbank. Ich kann bestätigen, dass das aus dem DB "budget_item" abgefragte Objekt von settattr aktualisiert wird. Am Ende der Passage verwende ich commit(), um das Objekt zu aktualisieren; Die Datenbank spiegelt jedoch die Änderungen nicht wider. Nur um zu testen, ob die Dinge fließen, habe ich session.add (budget_item) gefolgt von session.commit() versucht, um sicherzustellen, dass die Verbindung zur DB OK ist. Das funktioniert. Wie aktualisiere ich dieses budget_item-Objekt in der Datenbank? Jede Hilfe wird sehr geschätzt.

+1

Was versuchen Sie zu tun? Sie scheinen _50000! _ Neue Attribute zu einer _new_ 'Budget'-Instanz hinzuzufügen. Beachten Sie, dass das zweite "budget_item" eine andere Instanz ist als die, die Sie ursprünglich abgerufen haben. Da keines dieser Attribute im Mapping existiert (naja, ich nehme an, dass das nicht der Fall ist), hat das Aktualisieren des 'budget_item' keine Auswirkungen. Da es sich um eine _new_-Instanz handelt, müssen Sie sie der Sitzung hinzufügen. Vielleicht solltest du ein wenig mehr erklären, was du zu tun versuchst. – mhawke

Antwort

0

ich denke, dass ein einfaches

budget_item.budget_amount_reallocated_total = budget_amount_reallocated_total 
session.add(budget_item) 
session.commit() 

der richtige Weg ist es

+0

Leider bearbeitet dies nicht nur ein existierendes Objekt, es dupliziert das Objekt in der Datenbank ... lässt das alte Objekt zurück und fügt auch ein neues hinzu. – user3308477

0

zu tun, um Ihre Frage zu beantworten, aktualisieren die budget_item, die bereits in der Datenbank vorhanden ist Sie die Budget Instanz aktualisieren müssen, dass Sie aus der Datenbank abgerufen, dh

budget_item = session.query(Budget).filter_by(id=budget_id).one() 

nicht die, die Sie neu mit erstellt haben:

Hier steht die erste Zeile budget_item für die Zeile in der Datenbank, diese wird also aktualisiert. Zu diesem Zweck können Sie den Code ersetzen, der die zweite Budget Instanz mit diesem erzeugt:

budget_item.budget_transaction_type = request.form['transaction_type'] 
budget_item.budget_line = request.form['budget_line'] 
budget_item.amount = amount 
budget_item.description = request.form['description'] 

Sobald Sie die Budget Instanz abgeschlossen haben Aktualisieren Sie können session.commit() nennen es auf die Datenbank zu spülen.

Wie in meinem Kommentar zu Ihrer Frage erwähnt, scheint es, dass Sie versuchen, eine große Anzahl von zusätzlichen Attributen zu budget_item hinzuzufügen, die alle von sqlalchemy ignoriert werden, sofern sie nicht in der Zuordnung zwischen der Budget Instanz und der Budget Tabelle.

+0

Das ist genau richtig. Vielen Dank. Die Zeile budget_item = Budget (...) hat tatsächlich ein neues Objekt instanziiert und nicht nur das abgefragte Objekt aus der DB aktualisiert. Als ich es überarbeitet habe, wurde das ursprüngliche budget_item korrekt aktualisiert. Vielen Dank! (Wie für die zusätzlichen Attribute, ja, ich sollte den Code ändern. Mein HTML-Formular erlaubt nur 10 Attribute wie meine DB-Tabelle. Ich legte die Schleife auf 10000 mögliche Durchläufe für den Fall, dass ich später zurückkam, um weitere Attribute zum Frontend-Formular hinzuzufügen und die db-Tabelle.Im Moment stoppt die Schleife zu laufen und trifft und Ausnahme, wenn sie keine entsprechende POST Anfrage dict sind. – user3308477