繁体   English   中英

如何在一个对象中获取键值对,同时在 Python 中的 SQLAlchemy 中连接两个表?

[英]How to get key-value pair in one object while joining two tables in SQLAlchemy in Python?

我有两个表员工和部门,加入后我得到这样的结果

[
    {
      "name": "Omar Hasan",
      "id": 1,
      "email": "omar@example.com"
    },
    {
      "dept_name": "Engineering",
      "id": 2
    }
]

但我想要一个对象的结果,比如

[
    {
      "name": "Omar Hasan",
      "id": 1,
      "email": "omar@example.com",
      "dept_name": "Engineering",
    },
    ......
    ......
]

这是我的代码

模型,dept_id 在 Employee 表中是 FK

class Employee(Base):
    __tablename__ = "employees"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, index=True)
    email = Column(String, unique=True, index=True)
    password = Column(String)
    is_active = Column(Boolean, default=True)
    salary = Column(Numeric(10, 2))
    dept_id = Column(Integer, ForeignKey('departments.id'), nullable=False)

    department = relationship("Department", back_populates="owner")

class Department(Base):
    __tablename__ = "departments"

    id = Column(Integer, primary_key=True, index=True)
    dept_name = Column(String, unique=True, index=True)

    owner = relationship("Employee", back_populates="department")

这是产生上述结果的查询

return db.query(models.Employee, models.Department)\
        .join(models.Employee.department)\
        .options(
        Load(models.Employee).load_only("name", "email"),
        Load(models.Department).load_only("dept_name")
        )\
        .all()

您可以使用它们之间定义的关系来允许在构建结果时访问部门名称,而不是显式连接这两个模型。

# Query Employee only
res = session.query(Employee)\
        .options(
        orm.Load(Employee).load_only("name", "email"),
        orm.Load(Department).load_only("dept_name")
        )\
        .all()
 
mappings = []
for employee in res:
    d = {
        'name': employee.name,
        'id': employee.id,
        'email': employee.email,
        'dept_name' employee.department.name
    }
    mappings.append(d)

我们可以通过在Employee上定义一个部门名称属性来使构建结果字典更加优雅:

class Employee(Base):
    ...
    
    @property
    def dept_name(self):
        return self.department.dept_name

...

# List the attributes that we want
attrs = ['name', 'id', 'email', 'dept_name']
# Build the mappings using dictionary comprehensions
mappings = [{attr: getattr(e, attr) for attr in attrs} for e in res]

我们可以使用hybrid_property而不是标准property ,但在这里这样做没有太大价值,除非您想在查询中使用它。

暂无
暂无

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

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