简体   繁体   中英

Get column names along with table names for SQLAlchemy Query

I'm writing web api which passes SQL response queried via SQL Alchemy. I'd like to retrieve column names of the query WITH the source table.

Here's example:

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()
}

The "fields" variable will be dynamic, eg. user will be able to pass it as string list and I'd like to have a unified response from SQLAlchemy, not by iterating the fields variable.

With this query.column_descriptions I get column names as expected. However, those are only column names, without the source table name. So, in this case I get both "name" columns, which I'm not sure which name is it.

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

The class corresponding to the table comes in the 'entity' key. So, if you want a "tablename" key in your fields hash, you can do:

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()
}

Of course, you have the problem that your returns are null, at least in the return you have posted. This might have different reasons depending on your actual ORM and database data.

If instead you want the name of the column to be preceded by the name of the table, you might change the for loop above to

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

Using label could help in this case. For example

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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