我的表与其他表有深层嵌套关系
@mapper_registry.mapped
@dataclass
class Project:
__tablename__ = "project"
__table_args__ = (#some table constraints here)
id: float = field(init=False, metadata={"sa": Column(NUMBER(15, 0, False), primary_key=True)})
date_created: datetime = field(metadata={"sa": Column(MyTimestamp, nullable=False)})
user_created_id: float = field(metadata={"sa": Column(NUMBER(15, 0, False), nullable=False)})
user_created: Optional[BiologicsUser] = field(default=None, metadata={"sa": relationship("User", foreign_keys="Project.user_created_id", backref="project")})
mapper_registry.mapped
@dataclass
class User:
__tablename__ = "user"
__table_args__ = ()
__sa_dataclass_metadata_key__ = "sa"
id: float = field(
init=False, metadata={"sa": Column(NUMBER(15, 0, False), primary_key=True)}
)
name: str = field(metadata={"sa": Column(VARCHAR(100), nullable=False)})
organization_id: Optional[float] = field(default=None, metadata={"sa": Column(NUMBER(15, 0, False))})
department_id: Optional[float] = field(default=None, metadata={"sa": Column(NUMBER(15, 0, False))})
site_id: Optional[float] = field(default=None, metadata={"sa": Column(NUMBER(15, 0, False))})
department: Optional[Department] = field(default=None,metadata={"sa": relationship("Department", backref="user")})
organization: Optional[Organization] = field(default=None,metadata={"sa": relationship("Organization", backref="user")})
site: Optional[Site] = field(default=None,metadata={"sa": relationship("Organization", backref="user")})
@dataclass
class Department:
__tablename__ = "department"
__table_args__ = ( )
__sa_dataclass_metadata_key__ = "sa"
id: float = field(init=False, metadata={"sa": Column(NUMBER(15, 0, False), primary_key=True)})
label: str = field(metadata={"sa": Column(VARCHAR(255), nullable=False)})
@dataclass
class Organization:
__tablename__ = "organization"
__table_args__ = ( )
__sa_dataclass_metadata_key__ = "sa"
id: float = field(init=False, metadata={"sa": Column(NUMBER(15, 0, False), primary_key=True)})
label: str = field(metadata={"sa": Column(VARCHAR(255), nullable=False)})
@dataclass
class Site:
__tablename__ = "site"
__table_args__ = ( )
__sa_dataclass_metadata_key__ = "sa"
id: float = field(init=False, metadata={"sa": Column(NUMBER(15, 0, False), primary_key=True)})
label: str = field(metadata={"sa": Column(VARCHAR(255), nullable=False)})
当我使用
查询项目时session.execute(select(Project)).all()
我为项目中的所有列获取了一个嵌套字典/对象,并按预期嵌套了 user_created 列。但我不需要返回所有这些,因为它是一棵嵌套对象的大树。所以我尝试指定所需的字段
当我尝试选择 id 和 user_created
select(Project.id, Project.user_created)
例如,我收到错误
ORA-00923: FROM keyword not found where expected
E Help: https://docs.oracle.com/error-help/db/ora-00923/
E [SQL: SELECT project.id, user.id = project.user_created_id AS anon_1
E FROM project, user] - sqlalchemy.exc.DatabaseError: (oracledb.exceptions.DatabaseError) ORA-00923: FROM keyword not found where expected
我天真的想法是,既然我可以获得包括嵌套列在内的所有列,我应该能够只选择我需要的列并加载所有嵌套列。所以我尝试了
query = select(Project).options(load_only(Project.id, Project.user_created))
出现错误
Can't apply "column loader" strategy to property "Project.user_created", which is a "relationship"; this loader strategy is intended to be used with a "column property".
所以我改变了
query = select(Project).options(load_only(project.id), selectinload(Project.user_created))
还是失败了。不太确定我做错了什么。
这有点令人困惑,但我认为关键问题是列和关系之间的模糊区别。像
project.id
是一列,而 project.user_created
是一种关系,即。另一个模型。你必须以不同的方式对待这些。您可以通过在引擎上设置 echo=True
来检查会发生什么情况。
这里有几个例子:
id
列,然后使用另一个查询加载 user_created
关系。q = select(Project).options(load_only(Project.id), selectinload(Project.user_created))
for project in session.scalars(q):
print (project.id, project.user_created.id)
id
列和 user_created
对象,但您必须自己指定联接,这应该使用单个查询。q = select(Project.id, Project.user_created).join(Project.user_created)
for project_id, project_user_created in session.execute(q):
print (project.id, project.user_created.id)