如何从 SQLAlchemy 结果中获取列名(声明性语法)

发布于 2024-11-16 20:48:25 字数 481 浏览 2 评论 0原文

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

I am working in a pyramid project and I've the table in SQLAlchemy in declarative syntax

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

I get the results by using

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

How can I get the column names from this result.

PS: I am unable to use this method since I am using the declarative syntax.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

掩饰不了的爱 2024-11-23 20:48:26

您可以执行类似于 Foo Stack 的答案的操作,而无需诉诸私有字段,方法是:

conn.execute(query).keys()

You can do something similar to Foo Stack's answer without resorting to private fields by doing:

conn.execute(query).keys()
挽清梦 2024-11-23 20:48:26
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()
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))
    ...
    ...

Then this will return the columns names ['id', 'date', 'value', ...]:

Project.__table__.columns.keys()

Or this

Project.metadata.tables['table1'].columns.keys()
淤浪 2024-11-23 20:48:26

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

查询有一个为此目的添加的属性column_descriptions

https://docs.sqlalchemy.org/en/20/orm/queryguide/query.html#sqlalchemy.orm.Query.column_descriptions

The difference is between ORM and non-ORM, not declarative, which is just a helper for the ORM.

Query has an attribute column_descriptions that was added for this purpose:

https://docs.sqlalchemy.org/en/20/orm/queryguide/query.html#sqlalchemy.orm.Query.column_descriptions

情绪失控 2024-11-23 20:48:26

只是玩玩,这种语法将为您提供所有列(因此为了解决您的问题,请将查询设置为仅查看一个表/对象):

conn.execute(query)._metadata.keys

Just playing around, this syntax will give you all the columns (so to solve your problem, set query to look at one table/object only):

conn.execute(query)._metadata.keys
对岸观火 2024-11-23 20:48:26

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

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

Short answer is that I ended up with the following solution:

column_names = query.statement.columns.keys()

Why?

I had a similar use case where I need to know the explicit columns returned by a query (i.e., the query does not necessarily contain all columns of a table class). Since the table is also massive in size (millions of entries), prolibertas answer was not satisfying in terms of performance. Here a performance comparison on my table with 94 columns:

# 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
维持三分热 2024-11-23 20:48:26

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

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

This link shows how to get all the metadata you could ever need about a table, column and more.

SQLAlchemy Metadata

Many of the answers above are based on the info on this page.
Suppose we have declared a table.

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"))
)

Here are some examples of getting metadata about the table.

# 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
陌路黄昏 2024-11-23 20:48:26

>>> 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']
>>> 

Just

>>> q[0].keys()

After

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

Example :

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

Result :

>>> q[0].keys()
['phone', 'first_name']
>>> 
云醉月微眠 2024-11-23 20:48:26

在 2023 年手册中建议使用以下行:

colnames = query.statement.subquery().columns.keys()

或者如果您使用“执行”语句:

result = session.execute(text("SELECT * from my_table_name"))
print(result.keys()) 

In 2023 manual advise to use following lines:

colnames = query.statement.subquery().columns.keys()

or if you are using "execute" statement:

result = session.execute(text("SELECT * from my_table_name"))
print(result.keys()) 
ぇ气 2024-11-23 20:48:26

想扩展@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() ,无需任何过滤条件。

Would like to extend @zzzeek's answer. Indeed Query has column_descriptions attribute but it's not available for all the methods.

Consider the following two queries:

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

So if you come across this situation where you need to use column_descriptions attribute but using ...query(...).all() then you can change it to ...query(...).filter_by() i.e. filter_by() without any filter condition.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文