Here is the short example. On the last line, a query is issued to retrieve
the object, but the pending DELETE operation is not triggered by the
autoflush, resulting in an existing object instead of `None`. Can somebody
explain why?
us = Country(name="USA")
session.add(us)
session.commit()
session.delete(us)
self.assertIsNotNone(session.query(Country).get(us.id)) # "echo=True"
shows a SELECT query, but not the pending DELETE
self.assertIsNone(session.query(Country).get(us.id + 1)) # Executes the
pending DELETE as part of autoflush
self.assertIsNone(session.query(Country).get(us.id)) # executes another
SELECT -> gives None.
Having the order of the queries make results different seems like a
non-desirable behavior?
Interestingly, if the first query is *also* done before the `delete()`, we
get to the same result, because the query right after the `delete()` does
not execute any query.
us = Country(name="USA")
session.add(us)
session.commit()
self.assertIsNotNone(session.query(Country).get(us.id)) # "echo=True"
shows a SELECT query, normal
session.delete(us)
self.assertIsNotNone(session.query(Country).get(us.id)) # "echo=True"
shows nothing!
self.assertIsNone(session.query(Country).get(us.id + 1)) # Executes the
pending DELETE as part of autoflush
self.assertIsNone(session.query(Country).get(us.id)) # executes another
SELECT -> gives None.
---
Full example code is below:
import unittest
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, backref, sessionmaker
engine = create_engine('sqlite:///:memory:', echo=True)
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), unique=True)
country = relationship('Country', backref=backref('presidents'))
def __repr__(self):
return '<President {} [{}]>'.format(self.name, self.id)
Base.metadata.create_all(engine)
class TestSessionBasics(unittest.TestCase):
def setUp(self):
Base.metadata.create_all(engine)
def tearDown(self):
session.close()
Base.metadata.drop_all(engine)
def test_stuff(self):
us = Country(name="USA")
session.add(us)
session.commit()
print("Autoflush: ", session.autoflush)
print("\n\nDeleting\n")
session.delete(us)
print("\n\nChecking\n")
self.assertIsNotNone(session.query(Country).get(us.id))
print("\n\nFlushing\n")
session.flush()
print("\n\nChecking\n")
self.assertIsNone(session.query(Country).get(us.id))
print("\n\nComiting\n")
session.commit()
print("\n\nChecking\n")
self.assertIsNone(session.query(Country).get(us.id))
--
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.