2011-07-14 26 views

Trả lời

109

Lấy một đối tượng bằng cách sử dụng tutorial shown in the Flask-SQLAlchemy documentation. Khi bạn có thực thể mà bạn muốn thay đổi, hãy thay đổi thực thể. Sau đó, db.session.commit().

Ví dụ:

admin = User.query.filter_by(username='admin').first() 
admin.email = '[email protected]' 
db.session.commit() 

user = User.query.get(5) 
user.name = 'New Name' 
db.session.commit() 

Flask-SQLAlchemy được dựa trên SQLAlchemy, vì vậy hãy chắc chắn kiểm tra các SQLAlchemy Docs là tốt.

+1

Cảm ơn Mark. Một thứ khác. Tôi đã nhìn thấy nó thực hiện như thế này 'db.add (người dùng)' sau đó 'dv.session.commit()'. Tại sao cả hai làm việc?và sự khác biệt là gì? – pocorschi

+8

Điều này liên quan đến sự khác nhau giữa các đối tượng tạm thời, tách rời và được đính kèm trong SQLAlchemy (xem http://www.sqlalchemy.org/docs/orm/session.html#what-does-the-session-do). Ngoài ra, hãy đọc nhận xét của Michael Bayer về danh sách gửi thư (http://groups.google.com/group/sqlalchemy/browse_thread/thread/e38e2aba57aeed92?pli=1) để biết thêm thông tin. –

+1

Nếu bạn vẫn còn bối rối về sự khác biệt sau khi đọc qua đó, hãy cân nhắc đặt một câu hỏi khác. –

50

Có một phương thức update trên đối tượng BaseQuery trong SQLAlchemy, được trả về bởi filter_by.

admin = User.query.filter_by(username='admin').update(dict(email='[email protected]'))) 
db.session.commit() 

Lợi thế của việc sử dụng update thay đổi thực thể xuất hiện khi có nhiều đối tượng được cập nhật.

Nếu bạn muốn cho add_user phép tất cả các admin s,

rows_changed = User.query.filter_by(role='admin').update(dict(permission='add_user')) 
db.session.commit() 

ý rằng filter_by lấy đối số từ khóa (chỉ có một = sử dụng) như trái ngược với filter mà phải mất một biểu hiện.

13

Điều này không hoạt động nếu bạn sửa đổi thuộc tính đã chọn của mô hình. Phải thay thế các thuộc tính được chọn để kích hoạt cập nhật:

from flask import Flask 
from flask.ext.sqlalchemy import SQLAlchemy 
from pprint import pprint 

app = Flask(__name__) 
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqllite:////tmp/users.db' 
db = SQLAlchemy(app) 


class User(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(80), unique=True) 
    data = db.Column(db.PickleType()) 

    def __init__(self, name, data): 
     self.name = name 
     self.data = data 

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

db.create_all() 

# Create a user. 
bob = User('Bob', {}) 
db.session.add(bob) 
db.session.commit() 

# Retrieve the row by its name. 
bob = User.query.filter_by(name='Bob').first() 
pprint(bob.data) # {} 

# Modifying data is ignored. 
bob.data['foo'] = 123 
db.session.commit() 
bob = User.query.filter_by(name='Bob').first() 
pprint(bob.data) # {} 

# Replacing data is respected. 
bob.data = {'bar': 321} 
db.session.commit() 
bob = User.query.filter_by(name='Bob').first() 
pprint(bob.data) # {'bar': 321} 

# Modifying data is ignored. 
bob.data['moo'] = 789 
db.session.commit() 
bob = User.query.filter_by(name='Bob').first() 
pprint(bob.data) # {'bar': 321} 
+1

Cách tiếp cận tốt nhất trong những trường hợp như thế nào? – kampta

+0

Bạn sẽ phải sao chép 'dữ liệu' và gán lại nó. – sas

3

Chỉ định giá trị và cam kết chúng sẽ hoạt động cho tất cả các loại dữ liệu nhưng thuộc tính JSON và Pickled. Kể từ khi loại ngâm được giải thích ở trên tôi sẽ lưu ý xuống một cách hơi khác nhau nhưng dễ dàng để cập nhật JSON.

class User(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(80), unique=True) 
    data = db.Column(db.JSON) 

def __init__(self, name, data): 
    self.name = name 
    self.data = data 

Giả sử mô hình giống như trên.

user = User("Jon Dove", {"country":"Sri Lanka"}) 
db.session.add(user) 
db.session.flush() 
db.session.commit() 

này sẽ bổ sung thêm người dùng vào cơ sở dữ liệu MySQL với dữ liệu { "Đất nước": "Sri Lanka"}

dữ liệu Sửa đổi sẽ bị bỏ qua. Mã của tôi không hoạt động như sau.

user = User.query().filter(User.name=='Jon Dove') 
data = user.data 
data["province"] = "south" 
user.data = data 
db.session.merge(user) 
db.session.flush() 
db.session.commit() 

Thay vì thực hiện công việc đau đớn khi sao chép JSON sang lệnh mới (không gán nó cho biến mới như trên), tôi đã tìm cách đơn giản để thực hiện điều đó. Có một cách để gắn cờ hệ thống mà JSON đã thay đổi.

Sau đây là mã hoạt động.

from sqlalchemy.orm.attributes import flag_modified 
user = User.query().filter(User.name=='Jon Dove') 
data = user.data 
data["province"] = "south" 
user.data = data 
flag_modified(user, "data") 
db.session.merge(user) 
db.session.flush() 
db.session.commit() 

Điều này làm việc như một sự quyến rũ. Có một phương pháp khác được đề xuất cùng với phương pháp này here Hy vọng tôi đã giúp một số phương pháp.

Các vấn đề liên quan