Closed FilipeMarch closed 1 year ago
Relationship
does not work
from typing import Optional, List
from sqlmodel import Field, SQLModel, create_engine, Session, Relationship
class Worker(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str = Field(index=True)
transactions: List["Transaction"] = Relationship(
sa_relationship_kwargs={
"cascade": ""
}
)
class Transaction(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
worker_id: Optional[int] = Field(index=True, foreign_key="worker.id")
sqlite_file_name = "database/database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"
engine = create_engine(sqlite_url, echo=False)
SQLModel.metadata.create_all(engine)
# Create a worker
with Session(engine) as session:
worker = Worker(name='Worker 1')
session.add(worker)
session.commit()
session.refresh(worker)
# Create a transaction pointing to this worker
with Session(engine) as session:
transaction = Transaction(worker_id=worker.id)
session.add(transaction)
session.commit()
session.refresh(transaction)
# Delete the worker
with Session(engine) as session:
session.delete(worker)
session.commit()
# Print all transactions on database
with Session(engine) as session:
transactions = session.query(Transaction).all()
print(transactions)
The output:
>>> [Transaction(id=1, worker_id=1)]
Result is the same even using "cascade": "all, delete, delete-orphan"
Your models should look like this:
class Worker(SQLModel, table=True):
__table_args__ = {'sqlite_autoincrement': True}
id: Optional[int] = Field(default=None, primary_key=True)
name: str = Field(index=True)
transactions: List["Transaction"] = Relationship(back_populates="worker", sa_relationship_kwargs={ "cascade": "all,delete" })
class Transaction(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
worker_id: Optional[int] = Field(index=True, foreign_key="worker.id")
worker: Optional[Worker] = Relationship(back_populates="transactions")
Hello, @meirdev, thanks for the help, but this does not work here For me the result is the same:
from typing import Optional, List
from sqlmodel import Field, SQLModel, create_engine, Session, Relationship
class Worker(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str = Field(index=True)
transactions: List["Transaction"] = Relationship(
back_populates = "worker",
sa_relationship_kwargs = {"cascade": "all,delete"}
)
__table_args__ = {'sqlite_autoincrement': True}
class Transaction(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
worker_id: Optional[int] = Field(index=True, foreign_key="worker.id")
worker: Optional[Worker] = Relationship(back_populates = "transactions")
sqlite_file_name = "database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"
engine = create_engine(sqlite_url, echo=False)
SQLModel.metadata.create_all(engine)
# Create a worker
with Session(engine) as session:
worker = Worker(name='Worker 1')
session.add(worker)
session.commit()
session.refresh(worker)
# Create a transaction pointing to this worker
with Session(engine) as session:
transaction = Transaction(worker_id=worker.id)
session.add(transaction)
session.commit()
session.refresh(transaction)
# Delete the worker
with Session(engine) as session:
session.delete(worker)
session.commit()
# Print all transactions on database
with Session(engine) as session:
transactions = session.query(Transaction).all()
print(transactions)
The output:
[Transaction(id=1, worker_id=1)]
Use sqlalchemy <= 1.4.35, there are issues with version X>1.4.35 related to the Relationship field
Ok, I downgraded to sqlalchemy==1.4.30
and now it is working, thanks @meirdev
First Check
Commit to Help
Example Code
Description
Operating System
Linux
Operating System Details
Arch Linux containing
python-sqlalchemy 1.4.39-1
SQLModel Version
0.0.6
Python Version
3.10.5
Additional Context
I am having the same problem as this stackoverflow post
The problem is solved by
SQLAlchemy documentation
First, I don't know how to set
sqlite_autoincrement
with sqlmodel. I tried different things but didn't work. Second, I tried to create aRelationship
containingsa_relationship_kwargs={ "cascade": "all,delete" }
, but cascade simply does not work. When I delete the worker neither the transactions pointing to this worker are deleted, nor they become None. They are simply pointing to a non-existent worker.Then if I create a new worker, the new worker inherits the transactions from the deleted worker, this does not make any sense I would appreciate any idea on how to solve this. If I am able to use
sqlite_autoincrement
then new workers would never reuse the ID from previous workers, this would be a good solution.