Dưới đây là cách chính xác để thực hiện các thay đổi đối với một phiên bản mô hình và cam kết chúng vào cơ sở dữ liệu:
# get an instance of the 'Entry' model
entry = Entry.query.get(1)
# change the attribute of the instance; here the 'name' attribute is changed
entry.name = 'New name'
# now, commit your changes to the database; this will flush all changes
# in the current session to the database
db.session.commit()
Lưu ý: Không sử dụng SQLALCHEMY_COMMIT_ON_TEARDOWN
, vì nó được coi là có hại và cũng bị xóa khỏi tài liệu. Xem bảng thay đổi cho phiên bản 2.0
.
Chỉnh sửa: Nếu bạn có hai đối tượng của phiên bình thường (được tạo bằng sessionmaker()
) thay vì phiên theo phạm vi , sau đó gọi db.session.add(entry)
mã trên sẽ tạo ra lỗi sqlalchemy.exc.InvalidRequestError: Object '' is already attached to session '2' (this is '3')
. Để hiểu thêm về phiên sqlalchemy, hãy đọc phần bên dưới
Sự khác biệt chính giữa Phiên có phạm vi so với Phiên thông thường
Đối tượng phiên mà chúng tôi chủ yếu xây dựng từ sessionmaker()
cuộc gọi và được sử dụng để giao tiếp với cơ sở dữ liệu của chúng tôi là một phiên bình thường . Nếu bạn gọi sessionmaker()
lần thứ hai, bạn sẽ nhận được một đối tượng phiên mới có trạng thái độc lập với phiên trước đó. Ví dụ:giả sử chúng ta có hai đối tượng phiên được xây dựng theo cách sau:
from sqlalchemy import Column, String, Integer, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String)
from sqlalchemy import create_engine
engine = create_engine('sqlite:///')
from sqlalchemy.orm import sessionmaker
session = sessionmaker()
session.configure(bind=engine)
Base.metadata.create_all(engine)
# Construct the first session object
s1 = session()
# Construct the second session object
s2 = session()
Sau đó, chúng tôi sẽ không thể thêm cùng một đối tượng Người dùng vào cả s1
và s2
đồng thời. Nói cách khác, một đối tượng chỉ có thể được đính kèm nhiều nhất một đối tượng phiên duy nhất.
>>> jessica = User(name='Jessica')
>>> s1.add(jessica)
>>> s2.add(jessica)
Traceback (most recent call last):
......
sqlalchemy.exc.InvalidRequestError: Object '' is already attached to session '2' (this is '3')
Nếu các đối tượng phiên được truy xuất từ scoped_session
đối tượng, tuy nhiên, sau đó chúng tôi không gặp vấn đề như vậy vì scoped_session
đối tượng duy trì sổ đăng ký cho cùng một đối tượng phiên.
>>> session_factory = sessionmaker(bind=engine)
>>> session = scoped_session(session_factory)
>>> s1 = session()
>>> s2 = session()
>>> jessica = User(name='Jessica')
>>> s1.add(jessica)
>>> s2.add(jessica)
>>> s1 is s2
True
>>> s1.commit()
>>> s2.query(User).filter(User.name == 'Jessica').one()
Lưu ý rằng s1
và s2
là cùng một đối tượng phiên vì cả hai đều được truy xuất từ scoped_session
đối tượng duy trì một tham chiếu đến cùng một đối tượng phiên.
Mẹo
Vì vậy, hãy cố gắng tránh tạo nhiều hơn một phiên bình thường sự vật. Tạo một đối tượng của phiên và sử dụng nó ở mọi nơi từ khai báo mô hình đến truy vấn.