sql >> Databáze >  >> RDS >> PostgreSQL

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

Níže je uveden správný způsob, jak provést změny v instanci modelu a odeslat je do databáze:

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

Poznámka: Nepoužívejte SQLALCHEMY_COMMIT_ON_TEARDOWN , protože je považován za škodlivý a také odstraněn z dokumentů. Viz protokol změn verze 2.0 .

Upravit: Pokud máte dva objekty normální relace (vytvořeno pomocí sessionmaker() ) namísto relace v rozsahu a poté zavoláním db.session.add(entry) výše uvedený kód vyvolá chybu sqlalchemy.exc.InvalidRequestError: Object '' is already attached to session '2' (this is '3') . Další informace o relaci sqlalchemy naleznete níže v sekci

Velký rozdíl mezi omezenou relací a normální relací

Objekt relace jsme většinou vytvořili z sessionmaker() volání a používané ke komunikaci s naší databází je normální relace . Pokud zavoláte sessionmaker() podruhé získáte nový objekt relace, jehož stavy jsou nezávislé na předchozí relaci. Předpokládejme například, že máme dva objekty relace vytvořené následujícím způsobem:

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

Potom nebudeme moci přidat stejný objekt uživatele do obou s1 a s2 ve stejnou dobu. Jinými slovy, k objektu lze připojit maximálně jeden jedinečný objekt relace.

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

Pokud jsou objekty relace načteny z scoped_session objekt, pak však od scoped_session takový problém nemáme objekt udržuje registr pro stejný objekt relace.

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

Všimněte si, že s1 a s2 jsou stejným objektem relace, protože jsou oba načteny z scoped_session objekt, který udržuje odkaz na stejný objekt relace.

Tipy

Snažte se tedy vyhnout vytvoření více než jedné normální relace objekt. Vytvořte jeden objekt relace a použijte jej všude od deklarování modelů po dotazování.



  1. Jak aktualizovat a smazat seznam Zobrazit data v SQLite databázi pomocí click listeneru?

  2. Importujte soubor OSM do PostGis v systému Windows 10

  3. MySQL získá všechny ovlivněné řádky pro více příkazů v jednom dotazu

  4. Má java.net.Inet6Address.getByName doslova odejít a zjistit, zda adresa existuje