在同一会话中,删除对象后,会话中包含或指向此已删除对象的其他对象的关系属性不会更新。简而言之:
sesion.add(a, b)
a.parent = b
print(a.parent) # b
session.delete(b)
print(a.parent) # b
完整,可重复的例子如下。
我已阅读详细的SQLA文档,包括:
可以手动设置单个对象甚至单个对象属性,以使用session.expire()
重新加载。我认为ORM负责这项工作: - )
from sqlalchemy import create_engine, Table, 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)
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)
Base.metadata.create_all(engine)
# Creating both objects
us = Country(name="USA")
ny = Capital(name="NYC")
session.add(us)
session.add(ny)
session.commit()
print("\n### 1. Creating the relation:")
# Loading relations:
print("## us.capital: ", us.capital)
print("## ny.country: ", ny.country)
# Creating the relation:
us.capital = ny
# Checking that it's upated on the other side:
print("## ny.country (after rel creation): ", ny.country)
# Saving
session.commit()
print("\n### 2. Deleting relation:")
# Loading relations:
print("## us.capital: ", us.capital)
print("## ny.country: ", ny.country)
# Deleting one object of the relation:
us.capital = None
# The relation from the other side are updated accordingly
print("## ny.country (after rel deletion): ", ny.country)
# Rolling back
session.rollback()
print("\n### 3. Deleting one object:")
# Loading relations:
print("## us.capital: ", us.capital)
print("## ny.country: ", ny.country)
# Deleting one object of the relation:
session.delete(us)
# The relations are not updated!
print("## ny.country (after deletion of us): ", ny.country)
# Flushing doesn't change anything (undersantably so)
session.flush()
print("## ny.country (+ flush): ", ny.country)
# Expiring manually
session.expire(ny, ['country'])
# Looks okay
print("## ny.country (+ expire): ", ny.country)
# Rolling back
session.rollback()
print("\n### 4. Deleting the other object:")
# Loading relations:
print("## us.capital: ", us.capital)
print("## ny.country: ", ny.country)
# Deleting one object of the relation:
session.delete(ny)
# The relations are not updated!
print("## us.capital (after deletion of ny): ", us.capital)
# Flushing doesn't change anything (undersantably so)
session.flush()
print("## us.capital (+ flush): ", us.capital)
# Expiring manually
session.expire(us, ['capital'])
# Looks okay
print("## us.capital (+ expire): ", us.capital)
# Rolling back
session.rollback()
### 1. Creating the relation:
## us.capital: None
## ny.country: None
## ny.country (after rel creation): <Country USA [1]>
### 2. Deleting relation:
## us.capital: <Capital NYC [1]>
## ny.country: <Country USA [1]>
## ny.country (after rel deletion): None
### 3. Deleting one object:
## us.capital: <Capital NYC [1]>
## ny.country: <Country USA [1]>
## ny.country (after deletion of us): <Country USA [1]>
## ny.country (+ flush): <Country USA [1]>
## ny.country (+ expire): None
### 4. Deleting the other object:
## us.capital: <Capital NYC [1]>
## ny.country: <Country USA [1]>
## us.capital (after deletion of ny): <Capital NYC [1]>
## us.capital (+ flush): <Capital NYC [1]>
## us.capital (+ expire): None