import sqlalchemy as sa
from sqlalchemy.orm import backref, declarative_base, relationship, sessionmaker
Base = declarative_base()
class A(Base):
__tablename__ = "a"
id = sa.Column(sa.Integer, primary_key=True)
class B(Base):
__tablename__ = "b"
id = sa.Column(sa.Integer, sa.ForeignKey("a.id"), primary_key=True) name = sa.Column(sa.String)
# 1-to-1 relationship
a = relationship("A", backref=backref(
"b",
uselist=False,
# according to the docs, using a combination of delete-orphan
# with single_parent=True means that a B object can be deleted
# by doing A.b = None
cascade="all, delete-orphan",
single_parent=True,
))
engine = sa.create_engine("sqlite://", echo=True)
Base.metadata.create_all(engine)
Session = sessionmaker(engine)
with Session() as session:
a = A()
session.add(a)
a.b = B(name="foo")
session.commit()
# replace 'b' with a different object
a.b = B()
session.commit()
I would expect the print statement at the end to say "The value of '
b.name' is None" because a.b was last assigned to B(). But instead it says "The value of '
b.name' is foo".