2016-06-10 10 views
1

Ich habe eine Klasse weiter unten:Warum aktualisiert flask sql alchemy kein Attribut für einen Datensatz?

class Account(db.Model, flask_login.UserMixin): 
    __tablename__ = 'account' 
    id = db.Column(db.Integer, primary_key=True) 
    email = db.Column(db.String(75)) 
    username = db.Column(db.String(50)) 
    password = db.Column(db.String(250)) 
    admin = db.Column(db.Boolean) 

    def __init__(self, email='', username='', password='', admin=None): 
     self.email = email 
     self.username = username 
     self.password = password 
     self.admin = admin 

    def __repr__(self): 
     return '<Account %r>' % self.username 

Wenn ich ein Konto über ein Formular erstellen, wird das Admin-Attribut None sein. Wenn ich jedoch auf die Datenbank zugreife und versuche, sie manuell auf True zu setzen, wird das Attribut aktualisiert, aber wenn ich erneut auf die Datenbank zugreife, ist das Attribut None. Es ist super nervig.

Hier ist, was ich auf der Konsole ausführen:

account = Account.query.get(1) 
account.admin = True 
db.session.commit() 
db.admin ----> True 

exit() 

#restart again 
account = Account.query.get(1) 
account.admin ----> None 

Was mache ich falsch?

+0

"Get" muss nicht erneut den Datensatz abrufen. Sind Sie sicher, dass Sie eine saubere Sitzung haben, wenn 'account.admin'' None' ist? – univerio

+0

Wenn 'db.admin' kein Tippfehler ist (sollte' account.admin' sein), kann ich das Problem nicht reproduzieren. Bitte [bearbeiten], um ein [mcve] einzuschließen. – davidism

Antwort

1

Genau dies tun:

account = Account.query.get(1) 
account.admin = True 
db.session.merge(account) 
db.session.commit() 

Die Änderungen werden in der Datenbank erfasst und gesendet werden.

Die Instanz, die Sie haben, und das Objekt in der Sitzung sind nicht notwendigerweise die gleichen - obwohl sie dasselbe darstellen - sie sind nicht das gleiche Objekt. In Flask-SqlAlchemy gibt es eine SQLALCHEMY_TRACK_MODIFICATIONS-Konfiguration, die sqlalchemy wie gewünscht funktioniert. Aber es ist sehr teuer, da das Orm Änderungen an allen Instanzen überwachen muss.

Hoffe, das hilft!

-2

Die Änderung am Objekt wird nicht zur Sitzung hinzugefügt. So würde richtige Weg sein

account = Account.query.get(1) 
account.admin = True 
db.session.add(account) 
db.session.commit() 
+1

Warum würden Sie der Sitzung ein Konto hinzufügen? Es existiert bereits in der Datenbank, andernfalls wäre Account.query.get (1) keiner. –

+0

'db.session' wird nicht nur zum Erstellen eines neuen Datenbankeintrags verwendet, d. H. Die Aktualisierungen der Datenbank werden auch dadurch verwaltet. Also muss über __update query__ hinzugefügt werden. –

+0

Ich weiß, was db.session macht. Das Problem liegt in Ihrem db.session.add (account), das die Account-Instanz zur Sitzung hinzufügt und schließlich beim Aufruf von commit() zur Datenbank hinzugefügt wird. Siehe http://stackoverflow.com/questions/6699360/flask-sqlalchemy-update-a-rows-information –