SQLAlchemy:自动将列名映射到值

Posted

技术标签:

【中文标题】SQLAlchemy:自动将列名映射到值【英文标题】:SQLAlchemy: Map column name to value automatically 【发布时间】:2017-08-15 18:39:54 【问题描述】:

背景

当我想创建一个字典来将列名映射到结果中的值时,我需要单独列出每一列

    result = self.session.query(Project)\
                .join(Deadline)\
                .values(Project.project_id, Project.project_name,
                    Project.project_root, Deadline.deadline_time)

    output = []
    for row in result:
        r = 
        r['project_id'] = row.project_id
        r['project_name'] = row.project_name
        r['project_root'] = row.project_root
        r['deadline_time'] = row.deadline_time
        output.append(r)

    return output

模型是 ORM 映射的,不是 SQLAlchemy 核心。

class Deadline(Base):
    __tablename__ = 'deadline'

    deadline_id = Column(Integer, primary_key = True)
    deadline_time = Column(String, nullable = False)


class Project(Base):
    __tablename__ = 'project'

    project_id = Column(Integer, primary_key = True)
    project_name = Column(String, nullable = False)
    project_root = Column(String, nullable = False)
    deadline_id = Column(Integer, ForeignKey("deadline.deadline_id"), nullable=False)
    deadline = relationship("Deadline", primaryjoin = "Project.deadline_id == Deadline.deadline_id", backref=backref("project", uselist=False))

问题

这对于包含许多列的表来说效率不高,我也不能对其他表重复使用相同的代码。

我尝试了以下但无法获取列名

    column_names = [c["name"] for c in result.column_descriptions]
    return [dict(zip(column_names, row)) for row in result.all()]
    result.__table__.columns.keys() 

编辑 1

关于converting SQLAlchemy result into dict 有几个类似的问题。根据上面的代码,result.__table__.columns.keys() 不适用于 ORM 映射模型。

【问题讨论】:

Convert sqlalchemy row object to python dict的可能重复 【参考方案1】:

您的行是 SQLAlchemy KeyedTuple。由于 0.8 KeyedTuples 有 _asdict() 方法 - 你可以简单地使用:

output = []

for row in result:
    output.append(row._asdict())

PS。您不必在截止日期关系中指定这样一个微不足道的primaryjoin。 SQLAlchemy 将自行确定外键。

【讨论】:

【参考方案2】:

我相信你可以只使用字典理解:

r = k: row[k] for k in row

要将其包含在列表推导中的输出中:

output = [k: row[k] for k in row for row in result]

您可能只想将值附加到列表中,而不是在每行 JSON 样式中重复列名。

【讨论】:

【参考方案3】:

krassowski 的answer is exactly what I need。为简洁起见,我将_asdict() 应用为 lambda 函数。

result = self.session.query(Project)\
                .join(Deadline)\
                .values(Project.project_id, Project.project_name,
                    Project.project_root, Deadline.deadline_time)
map(lambda x: x._asdict(), result)

【讨论】:

以上是关于SQLAlchemy:自动将列名映射到值的主要内容,如果未能解决你的问题,请参考以下文章

将字典键映射到值的问题

SQLAlchemy怎么在Oracle中自动建立映射

可以将一系列键映射到值的数据结构

SQLAlchemy - 从自动加载表的内部连接映射列的子集

插入到自动映射生成的 ORM 时出现 SQLAlchemy InvalidRequestError

无法在 ETL 过程中使用 Pandas 和 SQLAlchemy 将列名从 CSV 更改为 SQL Server DB