When applying updates to a persistent object, it seems that each update is automatically pushed to the transaction buffer even when the autoflush property is set as false.
Consider the following example. There are two entities - Employee and Department, and they have a many-to-many relationship between them. The ORM definition is as follows:
from sqlalchemy.orm import registry, relationship
mapper_registry = registry()
mapper_registry.map_imperatively(
models.Employee,
employee_table,
properties={
"employee_id": employee_table.c.EmployeeId,
"first_name": employee_table.c.FirstName,
"last_name": employee_table.c.LastName,
"departments": relationship(
models.Department, secondary=joinEmployeeDepartment
),
},
)
The initial database state looks like this:
Employee:
| EmployeeId | FirstName | FirstName |
|---|---|---|
| 1 | John | Doe |
Department:
| DepartmentId | DepartmentName |
|---|---|
| 1 | Sales |
joinEmployeeDepartment:
| RelationshipId | EmployeeId | DepartmentId |
|---|---|---|
| 1 | 1 | 1 |
Then the following code is executed:
from sqlalchemy.orm.session import Session, sessionmaker
Session = sessionmaker(bind=engine, autocommit=False, autoflush=False, expire_on_commit=False)
session = Session()
session.begin()
try:
employee: Employee = session.query(Employee).where(Employee.first_name == 'John').one_or_none()
employee.departments = [Department(department_name='support')] # 1
employee.departments = [Department(department_name='IT')] # 2
session.commit()
finally:
session.close()
Since autoflush is turned off, I would expect that when the persistent employee object is updated in-memory in #1, the changes would not be flushed to transaction buffer. Since #2 overwrites the changes made in #1, only the latter would be flushed and committed when session.commit() is called. However, I observed that is not the case. The change in #1 is also added to the transaction buffer. The resulting DB state is as follows:
Department:
| DepartmentId | DepartmentName |
|---|---|
| 1 | Sales |
| 2 | support |
| 3 | IT |
joinEmployeeDepartment:
| RelationshipId | EmployeeId | DepartmentId |
|---|---|---|
| 2 | 1 | 3 |
My question is that is the autoflush setting ignored when updates are made to a persistent object?