Hieronder vindt u de juiste manier om wijzigingen aan te brengen in een modelinstantie en deze vast te leggen in de 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()
Opmerking: Gebruik geen SQLALCHEMY_COMMIT_ON_TEARDOWN
, omdat het als schadelijk wordt beschouwd en ook uit documenten wordt verwijderd. Zie de changelog voor versie 2.0
.
Bewerken: Als je twee objecten hebt van normale sessie (gemaakt met sessionmaker()
) in plaats van sessie met bereik , en vervolgens bij het aanroepen van db.session.add(entry)
bovenstaande code geeft fout sqlalchemy.exc.InvalidRequestError: Object '' is already attached to session '2' (this is '3')
. Voor meer begrip over sqlalchemy-sessie, lees het onderstaande gedeelte
Groot verschil tussen Scoped Session vs. Normal Session
Het sessie-object dat we meestal hebben geconstrueerd uit de sessionmaker()
oproep en gebruikt om te communiceren met onze database is een normale sessie . Als u sessionmaker()
. aanroept een tweede keer krijgt u een nieuw sessie-object waarvan de statussen onafhankelijk zijn van de vorige sessie. Stel dat we bijvoorbeeld twee sessie-objecten hebben die op de volgende manier zijn geconstrueerd:
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()
Dan kunnen we niet hetzelfde gebruikersobject toevoegen aan beide s1
en s2
tegelijkertijd. Met andere woorden, een object kan maximaal aan één uniek sessie-object worden gekoppeld.
>>> 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')
Als de sessie-objecten worden opgehaald uit een scoped_session
object, dan hebben we zo'n probleem niet meer sinds de scoped_session
object houdt een register bij voor hetzelfde sessie-object.
>>> 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()
Merk op dats1
en s2
zijn hetzelfde sessie-object omdat ze beide worden opgehaald uit een scoped_session
object dat een verwijzing naar hetzelfde sessie-object handhaaft.
Tips
Probeer dus te voorkomen dat u meer dan één normale sessie maakt object. Maak één object van de sessie en gebruik het overal, van het declareren van modellen tot het opvragen.