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 sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to