自引用表在数据库中是一种比较常见的数据结构,那么在SQLModel中怎么建立一个自引用的数据模型来对应这种数据表呢?主要原理还是参考一对多表结构的数据模型创建方式,在单一模型中建立一对多关系链。
注意:这里需要使用SQLAlchemy中的 remote_site 参数,参见 Relationships API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| from typing import Optional
from sqlmodel import Field, Relationship, Session, SQLModel, create_engine
class Node(SQLModel, table=True): __tablename__ = "node"
id: Optional[int] = Field(default=None, primary_key=True) data: str parent_id: Optional[int] = Field( foreign_key="node.id", default=None, nullable=True, ) parent: Optional["Node"] = Relationship( back_populates="children", sa_relationship_kwargs={ "remote_side": "Node.id", }, ) children: list["Node"] = Relationship(back_populates="parent")
def test() -> None: sqlite_file_name = "database.db" sqlite_uri = f"sqlite:///{sqlite_file_name}" engine = create_engine(sqlite_uri, echo=True) SQLModel.metadata.drop_all(engine) SQLModel.metadata.create_all(engine) session = Session(engine)
root_node = Node(data="I am root")
node_a = Node(parent=root_node, data="a") node_b = Node(parent=root_node, data="b") node_aa = Node(parent=node_a, data="aa") node_ab = Node(parent=node_a, data="ab")
node_ba = Node(data="ba") node_b.children.append(node_ba)
session.add(root_node) session.commit()
assert root_node.children == [node_a, node_b] assert node_aa.parent.parent.children[1].parent is root_node assert node_ba.parent.data == "b" assert all(n.data.startswith("a") for n in node_ab.parent.children) assert (node_ba.parent.parent.id == node_ba.parent.parent_id == root_node.id) assert isinstance(root_node.id, int)
if __name__ == "__main__": test()
|
来源:https://stackoverflow.com/questions/73420018/how-do-i-construct-a-self-referential-recursive-sqlmodel