62

我在一个金字塔项目中工作,并且我在 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:我无法使用方法,因为我使用的是声明性语法。

4

8 回答 8

66

您可以通过以下方式执行类似于 Foo Stack 的答案的操作,而无需求助于私有字段:

conn.execute(query).keys()
于 2015-07-30T21:45:51.350 回答
60
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()
于 2015-12-03T20:36:31.303 回答
36

区别在于ORM和非ORM,不是声明式的,它只是ORM的助手。

Query 有一个column_descriptions()为此目的添加的方法::

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

那里的例子似乎有一个错字,说q.columns但它应该是q.column_descriptions(编辑:刚刚修复它)。

于 2011-06-23T15:12:35.460 回答
12

随便玩玩,这个语法会给你所有的列(所以为了解决你的问题,设置查询只看一个表/对象):

conn.execute(query)._metadata.keys
于 2013-06-27T21:26:12.643 回答
7

此链接显示如何获取您可能需要的有关表、列等的所有元数据。

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
于 2019-08-04T22:25:34.550 回答
4

简短的回答是我最终得到了以下解决方案:

column_names = query.statement.columns.keys()

为什么?

我有一个类似的用例,我需要知道查询返回的显式列(即,查询不一定包含表类的所有列)。由于该表的大小也很大(数百万个条目),因此 prolibertas的答案在性能方面并不令人满意。这是我的表与 94 列的性能比较:

# First create a query with 100.000 entries
query = (
            session.query(myTable)
            .limit(100000)
        )

# Then get the column names .. 

column_names = session.execute(query).keys()
# ---> ~ 5.730 seconds

column_names = query.statement.columns.keys()
# ---> ~ 0.003 seconds
于 2021-10-20T21:27:14.043 回答
2

只是

>>> 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']
>>> 
于 2020-05-28T10:27:59.563 回答
-1

想扩展@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()then 的情况,您可以将其更改为...query(...).filter_by()ie filter_by(),而无需任何过滤条件。

于 2020-12-30T17:13:02.843 回答