Di bawah ini adalah cara yang benar untuk membuat perubahan pada instance model dan memasukkannya ke database:
# 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()
Catatan: Jangan gunakan SQLALCHEMY_COMMIT_ON_TEARDOWN
, karena dianggap berbahaya dan juga dihapus dari dokumen. Lihat log perubahan untuk versi 2.0
.
Sunting: Jika Anda memiliki dua objek sesi normal (dibuat menggunakan sessionmaker()
) alih-alih sesi cakupan , lalu saat memanggil db.session.add(entry)
kode di atas akan memunculkan kesalahan sqlalchemy.exc.InvalidRequestError: Object '' is already attached to session '2' (this is '3')
. Untuk pemahaman lebih lanjut tentang sesi sqlalchemy, baca bagian di bawah ini
Perbedaan Besar antara Sesi Cakupan vs. Sesi Normal
Objek sesi yang sebagian besar kita buat dari sessionmaker()
panggilan dan digunakan untuk berkomunikasi dengan database kami adalah sesi normal . Jika Anda memanggil sessionmaker()
untuk kedua kalinya, Anda akan mendapatkan objek sesi baru yang statusnya tidak bergantung pada sesi sebelumnya. Misalnya, kita memiliki dua objek sesi yang dibangun dengan cara berikut:
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()
Kemudian, kami tidak akan dapat menambahkan objek Pengguna yang sama ke s1
dan s2
pada saat yang sama. Dengan kata lain, sebuah objek hanya dapat dilampirkan paling banyak satu objek sesi unik.
>>> 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')
Jika objek sesi diambil dari scoped_session
objek, bagaimanapun, maka kami tidak memiliki masalah seperti itu sejak scoped_session
objek memelihara registri untuk objek sesi yang sama.
>>> 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()
Perhatikan bahwas1
dan s2
adalah objek sesi yang sama karena keduanya diambil dari scoped_session
objek yang mempertahankan referensi ke objek sesi yang sama.
Kiat
Jadi, cobalah untuk tidak membuat lebih dari satu sesi normal obyek. Buat satu objek sesi dan gunakan di mana saja mulai dari mendeklarasikan model hingga membuat kueri.