Как получить имена столбцов из результата SQLAlchemy (декларативный синтаксис)

Я работаю в проекте пирамиды, и у меня есть таблица в SQLAlchemy в декларативном синтаксисе.

"""models.py"""
class Projects(Base):
    __tablename__ = 'projects'
    __table_args__ = {'autoload': True}

Я получаю результаты, используя

""""views.py"""
session = DBSession()
row_data = session.query(Projects).filter_by(id=1).one()

Как я могу получить имена столбцов из этого результата.

PS: я не могу использовать этот метод, так как я использую декларативный синтаксис.


person Sukumar    schedule 23.06.2011    source источник


Ответы (7)


Разница между ORM и не-ORM, а не декларативность, которая является просто помощником для ORM.

В запросе есть метод column_descriptions(), который был добавлен для этой цели:

http://www.sqlalchemy.org/docs/orm/query.html#sqlalchemy.orm.query.Query.column_descriptions

в примере кажется, что в нем есть опечатка, говорит q.columns, но должно быть q.column_descriptions (редактировать: только что исправил).

person zzzeek    schedule 23.06.2011
comment
Спасибо за ответ! К сожалению, это возвращает [{'aliased': False, 'expr': ‹class 'metrics.models.Projects'›, 'type': ‹class 'metrics.models.Projects'›, 'name': 'Projects'} ] Я пытаюсь использовать отражение, чтобы мне не нужно было указывать имя столбца, и с помощью этого метода мне все равно придется указывать имена столбцов. Или я что-то упускаю? - person Sukumar; 27.06.2011
comment
Я думаю, что нашел решение. Мне удалось получить список столбцов с помощью Projects.__table__.columns.keys() - person Sukumar; 27.06.2011
comment
Я думаю, что это работает, только если вы указываете, какие столбцы вы хотите вернуть в запросе (что означает, что вы уже знаете имена столбцов). Что @Sukumar и мне нужно, так это столбцы для запроса, построенного как q=sess.query(MyTableObject).all() - person medley56; 23.01.2020
comment
column_descriptions — это атрибут, а не метод. - person wolfmanx; 15.07.2020

Вы можете сделать что-то похожее на ответ Foo Stack, не прибегая к закрытым полям, выполнив:

conn.execute(query).keys()
person prolibertas    schedule 30.07.2015
comment
Я знаю, что это старый ответ, но надеюсь, что кто-то знает: если запрос предназначен для более чем одного объекта, как получить однозначные имена столбцов? Для такого запроса, как Query(DataClass1).join(DataClass2).add_entity(DataClass2), если DataClass1 и DataClass2 имеют поля с одинаковыми именами, то keys() возвращает список с повторяющимися записями. - person Tom; 24.08.2020

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import (Column, Index, Date, DateTime, Numeric, BigInteger, String, ForeignKey, Boolean)

Base = declarative_base()

class Project(Base):
    """sqlalchemy ORM for my table."""
    __tablename__ = "table1"
    id = Column("id", BigIntegerID, primary_key=True, autoincrement=True)
    date = Column("date", Date, nullable=False)
    value = Column("value", Numeric(20, 8))
    ...
    ...

Затем это вернет имена столбцов ['id', 'date', 'value',...]:

Project.__table__.columns.keys()

Или это

Project.metadata.tables['table1'].columns.keys()
person Lydia    schedule 03.12.2015
comment
Обратите внимание, что «столбцы» взаимозаменяемы с «c», поэтому для вышеуказанного Project.metadata.tables[Project.__tablename__].c.keys() также будет работать. Как и Project.__table__.c.keys() - person CubeBot88; 20.06.2017

Просто играя, этот синтаксис даст вам все столбцы (поэтому, чтобы решить вашу проблему, установите запрос для просмотра только одной таблицы/объекта):

conn.execute(query)._metadata.keys
person Foo Stack    schedule 27.06.2013
comment
он все еще там 5 лет спустя. Единственный способ сделать что-то надежное — положиться на него. - person Grail Finder; 09.05.2018
comment
Хороший! Это будет полезно в методе свойства (установщика) - person Jcc.Sanabria; 21.12.2018

По этой ссылке показано, как получить все метаданные, которые могут вам когда-либо понадобиться о таблице, столбце и многом другом.

Метаданные SQLAlchemy

Многие из приведенных выше ответов основаны на информации на этой странице. Предположим, мы объявили таблицу.

employees = Table('employees', metadata,
    Column('employee_id', Integer, primary_key=True),
    Column('employee_name', String(60), nullable=False),
    Column('employee_dept', Integer, ForeignKey("departments.department_id"))
)

Вот несколько примеров получения метаданных о таблице.

# access the column "EMPLOYEE_ID":
employees.columns.employee_id

# or just
employees.c.employee_id

# via string
employees.c['employee_id']

# iterate through all columns
for c in employees.c:
    print(c)

# get the table's primary key columns
for primary_key in employees.primary_key:
    print(primary_key)

# get the table's foreign key objects:
for fkey in employees.foreign_keys:
    print(fkey)

# access the table's MetaData:
employees.metadata

# access the table's bound Engine or Connection, if its MetaData is bound:
employees.bind

# access a column's name, type, nullable, primary key, foreign key
employees.c.employee_id.name
employees.c.employee_id.type
employees.c.employee_id.nullable
employees.c.employee_id.primary_key
employees.c.employee_dept.foreign_keys

# get the "key" of a column, which defaults to its name, but can
# be any user-defined string:
employees.c.employee_name.key

# access a column's table:
employees.c.employee_id.table is employees

# get the table related by a foreign key
list(employees.c.employee_dept.foreign_keys)[0].column.table
person Mark Kortink    schedule 04.08.2019

Просто

>>> q[0].keys()

После

row_data = session.query(Projects).filter_by(id=1).one()

Пример :

>>> q = session.query(users_user.phone,users_user.first_name).filter(users_user.phone=='79267548577').limit(1).all()
>>> columns_names = q[0].keys

Результат :

>>> q[0].keys()
['phone', 'first_name']
>>> 
person Артемий Шувалов    schedule 28.05.2020

Хотел бы расширить ответ @zzzeek. Действительно, у Query есть атрибут column_descriptions, но он доступен не для всех методов.

Рассмотрим следующие два запроса:

1. query = session.query(Projects).filter_by(<filter_condition>)
2. query = session.query(Projects).all() <-- This query does not have column_descriptions.

Поэтому, если вы столкнетесь с ситуацией, когда вам нужно использовать атрибут column_descriptions, но используя ...query(...).all(), вы можете изменить его на ...query(...).filter_by(), т.е. filter_by() без каких-либо условий фильтра.

person Abu Shumon    schedule 30.12.2020