1

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": []
}

2 Answers 2

1

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'])
Sign up to request clarification or add additional context in comments.

1 Comment

This is the exact thing I needed. Thanks a lot!
1

Using label could help in this case. For example

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

1 Comment

This would be good if I fields were not mutable by the users, however they're to change. Thanks, anyhow.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.