По-долу е правилният начин за извършване на промени в екземпляр на модел и записването им в базата данни:
# 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()
Забележка: Не използвайте SQLALCHEMY_COMMIT_ON_TEARDOWN
, тъй като се счита за вреден и също така е премахнат от документите. Вижте дневника на промените за версия 2.0
.
Редактиране: Ако имате два обекта от нормална сесия (създадено с помощта на sessionmaker()
) вместо сесия с обхват , след това при извикване на db.session.add(entry)
горният код ще доведе до грешка sqlalchemy.exc.InvalidRequestError: Object '' is already attached to session '2' (this is '3')
. За повече разбиране относно сесията на sqlalchemy, прочетете раздела по-долу
Основна разлика между сесия с обхват спрямо нормална сесия
Обектът на сесията, който основно конструирахме от sessionmaker()
повикване и използване за комуникация с нашата база данни е нормална сесия . Ако извикате sessionmaker()
втори път ще получите нов сесиен обект, чиито състояния са независими от предишната сесия. Да предположим например, че имаме два обекта на сесия, конструирани по следния начин:
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()
Тогава няма да можем да добавим един и същ потребителски обект към двата s1
и s2
по същото време. С други думи, един обект може да бъде прикачен само до един уникален сесиен обект.
>>> 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')
Ако обектите на сесията са извлечени от scoped_session
обект обаче, тогава нямаме такъв проблем след scoped_session
обектът поддържа регистър за същия обект на сесия.
>>> 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()
Забележете, че s1
и s2
са един и същ обект на сесия, тъй като и двата са извлечени от scoped_session
обект, който поддържа препратка към същия обект на сесия.
Съвети
Така че, опитайте се да избягвате създаването на повече от една нормална сесия обект. Създайте един обект от сесията и го използвайте навсякъде от деклариране на модели до заявки.