sql >> Database teknologi >  >> RDS >> PostgreSQL

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

Nedenfor er den korrekte måde at foretage ændringer på en modelforekomst og forpligte dem til databasen:

# 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()

Bemærk: Brug ikke SQLALCHEMY_COMMIT_ON_TEARDOWN , da det anses for at være skadeligt og også fjernet fra dokumenter. Se ændringsloggen for version 2.0 .

Rediger: Hvis du har to objekter af normal session (oprettet ved hjælp af sessionmaker() ) i stedet for session med omfang , og derefter ved at kalde db.session.add(entry) ovenstående kode vil give fejlen sqlalchemy.exc.InvalidRequestError: Object '' is already attached to session '2' (this is '3') . For mere forståelse om sqlalchemy session, læs nedenstående afsnit

Stor forskel mellem omfangssession vs normal session

Sessionsobjektet konstruerede vi for det meste fra sessionmaker() opkald og bruges til at kommunikere med vores database er en normal session . Hvis du kalder sessionmaker() en anden gang vil du få et nyt sessionsobjekt, hvis tilstande er uafhængige af den forrige session. Antag for eksempel, at vi har to sessionsobjekter konstrueret på følgende måde:

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()

Så vil vi ikke være i stand til at tilføje det samme brugerobjekt til begge s1 og s2 på samme tid. Med andre ord kan et objekt højst vedhæftes ét unikt sessionsobjekt.

>>> 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')

Hvis sessionsobjekterne hentes fra en scoped_session objekt, så har vi ikke et sådant problem siden scoped_session objekt vedligeholder et register for det samme sessionsobjekt.

>>> 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()

Bemærk at s1 og s2 er det samme sessionsobjekt, da de begge er hentet fra en scoped_session objekt, der opretholder en reference til det samme sessionsobjekt.

Tips

Så prøv at undgå at oprette mere end én normal session objekt. Opret ét objekt i sessionen, og brug det overalt fra deklarerende modeller til forespørgsler.



  1. Kompleks Wordpress-forespørgsel ved hjælp af flere forespørgsler

  2. Enterprise Architect - Microsoft OLE DB Provider til ODBC-drivere -2147217900 / '80040E14'

  3. Sender SQL-operatorer til at forespørge gennem iReport-parameter

  4. Tjek, om SQL-serveren (en hvilken som helst version) er installeret?