PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

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


Abaixo está a maneira correta de fazer alterações em uma instância de modelo e confirmá-las no banco de dados:
# 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()

Observação: Não use SQLALCHEMY_COMMIT_ON_TEARDOWN , pois é considerado prejudicial e também removido dos documentos. Consulte o registro de alterações da versão 2.0 .

Editar: Se você tiver dois objetos de sessão normal (criado usando sessionmaker() ) em vez de sessão com escopo , então ao chamar db.session.add(entry) o código acima gerará o erro sqlalchemy.exc.InvalidRequestError: Object '' is already attached to session '2' (this is '3') . Para mais compreensão sobre a sessão sqlalchemy, leia a seção abaixo

Grande diferença entre a sessão com escopo e a sessão normal


O objeto de sessão que construímos principalmente a partir do sessionmaker() chamada e usada para se comunicar com nosso banco de dados é uma sessão normal . Se você chamar sessionmaker() uma segunda vez, você obterá um novo objeto de sessão cujos estados são independentes da sessão anterior. Por exemplo, suponha que temos dois objetos de sessão construídos da seguinte maneira:
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()

Então, não poderemos adicionar o mesmo objeto User a ambos s1 e s2 ao mesmo tempo. Em outras palavras, um objeto só pode ser anexado no máximo a um objeto de sessão exclusivo.
>>> 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')

Se os objetos de sessão forem recuperados de uma scoped_session objeto, no entanto, não temos esse problema, pois a scoped_session objeto mantém um registro para o mesmo objeto de sessão.
>>> 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()

Observe que s1 e s2 são o mesmo objeto de sessão, pois ambos são recuperados de uma scoped_session objeto que mantém uma referência ao mesmo objeto de sessão.

Dicas


Portanto, tente evitar criar mais de uma sessão normal objeto. Crie um objeto da sessão e use-o em todos os lugares, desde a declaração de modelos até a consulta.