【问题标题】:Get column names along with table names for SQLAlchemy Query获取 SQLAlchemy 查询的列名和表名
【发布时间】:2019-08-28 00:58:00
【问题描述】:

我正在编写传递通过 SQL Alchemy 查询的 SQL 响应的 web api。我想用源表检索查询的列名。

这是一个例子:

fields = [
    StudentsTable.name,
    SubjectsTable.name
]

query = self.session()\
    .query(*fields)\
    .filter(StudentsTable.id_some_fk == SubjectsTable.id_some_pk)

return {
    "meta": {
        "fields": query.column_descriptions
    },
    "data": query.all()
}

“字段”变量将是动态的,例如。用户将能够将其作为字符串列表传递,我希望得到 SQLAlchemy 的统一响应,而不是通过迭代 fields 变量。

有了这个query.column_descriptions,我得到了预期的列名。但是,这些只是列名,没有源表名。所以,在这种情况下,我得到两个“名称”列,我不确定它是哪个名称。

{
    "meta": {
        "fields": [
            {
                "name": "name",
                "type": null,
                "aliased": false,
                "expr": null,
                "entity": null
            },
            {
                "name": "name",
                "type": null,
                "aliased": false,
                "expr": null,
                "entity": null
            }
        ]
    },
    "data": []
}

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    对应表的类在'entity'键中。所以,如果你想在你的字段散列中有一个“tablename”键,你可以这样做:

    fields = [
        StudentsTable.name,
        SubjectsTable.name
    ]
    
    query = self.session()\
        .query(*fields)\
        .filter(StudentsTable.id_some_fk == SubjectsTable.id_some_pk)
    
    descriptions = query.column_descriptions
    
    for description in descriptions:
        description['tablename'] = description['entity'].__tablename__
    
    return {
        "meta": {
            "fields": descriptions
        },
        "data": query.all()
    }
    

    当然,您的退货是空的,至少在您发布的退货中是这样。这可能有不同的原因,具体取决于您的实际 ORM 和数据库数据。

    如果您希望列名前面有表名,则可以将上面的 for 循环更改为

    for description in descriptions:
        description['name'] = "{}.{}".format(description['entity'].__tablename__, description['name'])
    

    【讨论】:

    • 这正是我所需要的。非常感谢!
    【解决方案2】:

    在这种情况下使用标签可能会有所帮助。例如

    fields = [
        StudentsTable.name.label('student_name'),
        SubjectsTable.name.label('subject_name')
    ]
    

    【讨论】:

    • 如果我的字段不能被用户改变,这会很好,但是他们要改变。无论如何,谢谢。
    猜你喜欢
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    • 2012-07-16
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多