sql >> Database >  >> RDS >> PostgreSQL

Flask-SQLAalchemy db.session.query(Model) vs Model.query

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.



  1. SQL Server 2008 Prestaties op nullable geografiekolom met ruimtelijke index

  2. SQL Update en vervang substring

  3. SQL UPDATE-syntaxis - weergegeven door DBMS

  4. Zoekopdracht in slaapstand