简体   繁体   English

sqlalchemy 自引用中的 column_property

[英]sqlalchemy column_property in self-referential

I can't describe the column "invited_name" (column_property).我无法描述列“invited_name”(column_property)。 I don't know how to do this correctly.我不知道如何正确地做到这一点。

class Worker(declarative_base()):
    __tablename__ = "staff_worker_info"

    id = Column(Integer, primary_key=True)
    first_name = Column(String(40), nullable=False)
    last_name = Column(String(40), nullable=False)

    invited_id = Column(Integer, ForeignKey('staff_worker_info.id'))
    invited = relationship("Worker", uselist=False, remote_side=[id], join_depth=1)

    # I don't know how to describe this column
    invited_name = column_property(
         select([Worker.first_name]). \
         where(Worker.id == invited_id).\
         label('invited_n'))

I understand why this doesn't work, but I don't know how to write it differently.我明白为什么这不起作用,但我不知道如何以不同的方式编写它。

I should get such a SQL query.我应该得到这样一个 SQL 查询。

SELECT staff_worker_info.id, staff_worker_info.first_name staff_worker_info.last_name, staff_worker_info.invited_id,
        (SELECT worker_invited.first_name  
         FROM staff_worker_info AS worker_invited
         WHERE staff_worker_info.invited_id = worker_invited.id) AS invited_n,
FROM staff_worker_info 

Might be a bit late, but I recently faced a similar question.可能有点晚了,但我最近遇到了类似的问题。 I think your problem is quite easy to solve with only the relationship.我认为您的问题仅通过关系很容易解决。 If you want you can also solve it by using a column_property .如果你愿意,你也可以使用column_property来解决它。

First, using the relationship.第一,利用关系。 If you make the invited relationship joined, then the actual query that is send to the database is a self-join.如果您使受邀关系加入,那么发送到数据库的实际查询是自加入。 You can access the first name via that relationship (reference https://docs.sqlalchemy.org/en/14/orm/self_referential.html ).您可以通过该关系访问名字(参考https://docs.sqlalchemy.org/en/14/orm/self_referential.html )。

class Worker(declarative_base()):
    __tablename__ = "staff_worker_info"

    id = Column(Integer, primary_key=True)
    first_name = Column(String(40), nullable=False)
    last_name = Column(String(40), nullable=False)

    invited_id = Column(Integer, ForeignKey('staff_worker_info.id'))
    invited = relationship("Worker", uselist=False, remote_side=[id], join_depth=1, lazy='joined')
    
    @property
    def invited_name(self):
        return self.invited.first_name

Then, if the query you want to do is more complex, and it requires you to create a column_property , you can also do it as follows (reference https://docs.sqlalchemy.org/en/14/orm/mapped_sql_expr.html ):然后,如果你想做的查询比较复杂,它需要你创建一个column_property ,你也可以这样做(参考https://docs.sqlalchemy.org/en/14/orm/mapped_sql_expr.html ):

from sqlalchemy import inspect
from sqlalchemy.orm import aliased

class Worker(declarative_base()):
    __tablename__ = "staff_worker_info"

    id = Column(Integer, primary_key=True)
    first_name = Column(String(40), nullable=False)
    last_name = Column(String(40), nullable=False)

    invited_id = Column(Integer, ForeignKey('staff_worker_info.id'))
    invited = relationship("Worker", uselist=False, remote_side=[id], join_depth=1)

# Requires alias
worker = aliased(Worker)
inspect(Worker).add_property(
   "invited_name",
   column_property(
         select([worker.first_name]). \
         where(worker.id == Worker.invited_id)
   )
)

I found a method.我找到了一个方法。 But he did not like it.但他不喜欢。

invited_name = column_property(
        select([text("invited_table.first_name")]).
            where(text("invited_table.id = staff_worker_info.invited_id")).
            select_from(text("staff_worker_info AS invited_table")).
            label('invited_n'))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM