Here is a simple example:
us = Country(name="USA")
session.add(us)
session.commit()
session.delete(us)
assert session.query(Country).get(us.id) is not None # Issues a SELECT
query alone
session.query(Country).get(us.id + 1) # Issues a SELECT with the flushed
DELETE
assert session.query(Country).get(us.id) is None # -> Now it's none
What is the explanation here for what seems to be a breach of the
'autoflush' contract? Is there other cases where autoflush doesn't behave
as desired?
It seems undesirable to have a different result based on the order of the
query.
Related:
Interestingly enough, if we do the same query *before* the delete, the one
right after doesn't issue a query to the transaction, and leads to the same
result. Could that be linked to the previous example's behavior?
us = Country(name="USA")
session.add(us)
session.commit()
session.query(Country).get(us.id) is not None # Issues a SELECT query alone
session.delete(us)
assert session.query(Country).get(us.id) is not None # Issues nothing
session.query(Country).get(us.id + 1) # Issues a SELECT with the flushed
DELETE
assert session.query(Country).get(us.id) is None # -> Now it's none
FULL CODE:
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, backref, sessionmaker
VERBOSE = True
def printv(*args):
if VERBOSE:
print("\n\n", *args, "\n")
engine = create_engine('sqlite:///:memory:', echo=VERBOSE)
Base = declarative_base()
Session = sessionmaker(bind=engine, autoflush=True)
session = Session()
class Country(Base):
__tablename__ = 'countries'
id = Column(Integer(), primary_key=True)
name = Column(String(255))
def __repr__(self):
return '<Country {} [{}]>'.format(self.name, self.id)
class Capital(Base):
__tablename__ = 'capitals'
id = Column(Integer(), primary_key=True)
name = Column(String(255))
country_id = Column(Integer(), ForeignKey(Country.id), unique=True)
country = relationship('Country', backref=backref('capital', uselist=
False))
def __repr__(self):
return '<Capital {} [{}]>'.format(self.name, self.id)
class President(Base):
__tablename__ = 'presidents'
id = Column(Integer(), primary_key=True)
name = Column(String(255))
country_id = Column(Integer(), ForeignKey(Country.id))
country = relationship('Country', backref=backref('presidents'))
def __repr__(self):
return '<President {} [{}]>'.format(self.name, self.id)
Base.metadata.create_all(engine)
us = Country(name="USA")
session.add(us)
session.commit()
printv("Deleting")
session.delete(us)
printv("Querying")
assert session.query(Country).get(us.id) is not None # Issues a SELECT
query alone
printv("Querying something else")
session.query(Country).get(us.id + 1) # Issues a SELECT with the flushed
DELETE
printv("Querying again")
assert session.query(Country).get(us.id) is None # -> Now it's none
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
http://www.sqlalchemy.org/
To post example code, please provide an MCVE: Minimal, Complete, and Verifiable
Example. See http://stackoverflow.com/help/mcve for a full description.
---
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.