【问题标题】:sqlalchemy column_property in self-referential自引用中的sqlalchemy column_property
【发布时间】:2022-02-10 02:31:04
【问题描述】:

我无法描述“invited_name”列(column_property)。我不知道如何正确地做到这一点。

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'))

我明白为什么这不起作用,但我不知道如何以不同的方式编写它。

我应该得到这样一个 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 

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    可能有点晚了,但我最近遇到了类似的问题。我认为你的问题很容易解决,只有关系。如果您愿意,也可以使用column_property 来解决它。

    首先,使用关系。如果您使受邀关系联接,则发送到数据库的实际查询是自联接。您可以通过该关系访问名字(参考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
    

    那么,如果你要做的查询比较复杂,需要你创建一个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)
       )
    )
    
    

    【讨论】:

      【解决方案2】:

      我找到了一个方法。但他不喜欢。

      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'))
      

      【讨论】:

        猜你喜欢
        • 2019-07-13
        • 2012-08-23
        • 1970-01-01
        • 1970-01-01
        • 2015-01-31
        • 1970-01-01
        • 2023-03-17
        • 2022-10-18
        • 2018-04-24
        相关资源
        最近更新 更多