【问题标题】:How to get column names from SQLAlchemy result (declarative syntax)如何从 SQLAlchemy 结果中获取列名(声明性语法)
【发布时间】:2011-09-21 06:49:24
【问题描述】:

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

【问题讨论】:

    标签: python sqlalchemy pylons pyramid


    【解决方案1】:

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

    conn.execute(query).keys()
    

    【讨论】:

    • 我知道这是一个旧答案,但希望有人知道:如果查询是针对多个实体的,您如何获得明确的列名?对于像Query(DataClass1).join(DataClass2).add_entity(DataClass2) 这样的查询,如果DataClass1DataClass2 具有相同名称的字段,则keys() 返回一个包含重复条目的列表。
    【解决方案2】:
    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()
    

    【讨论】:

    • 请注意,'columns' 可以与 'c' 互换,因此对于上述 Project.metadata.tables[Project.__tablename__].c.keys() 也可以使用。与 Project.__table__.c.keys() 一样
    【解决方案3】:

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

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

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

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

    【讨论】:

    • 感谢您的回答!不幸的是,这会返回 [{'aliased': False, 'expr': , 'type': , 'name': 'Projects'} ] 我正在尝试使用反射,这样我就不必指定列名,并且使用这种方法我仍然必须指定列名。还是我错过了什么?
    • 我想我找到了解决方案。我能够使用 Projects.__table__.columns.keys() 获取列列表
    • 我认为这仅在您指定要在查询中返回哪些列时才有效(这意味着您已经知道列名)。 @Sukumar 和我需要的是像 q=sess.query(MyTableObject).all() 这样构造的查询的列
    • column_descriptions 是一个属性,而不是一个方法。
    【解决方案4】:

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

    conn.execute(query)._metadata.keys
    

    【讨论】:

    • 5 年后它仍然存在。只有依靠它,你才能做出可靠的东西。
    • 不错!它在属性(setter)方法中很有用
    【解决方案5】:

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

    SQLAlchemy Metadata

    上面的许多答案都是基于此页面上的信息。 假设我们声明了一个表。

    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
    

    【讨论】:

    • 太棒了!我学到了一些东西,而不仅仅是复制
    【解决方案6】:

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

    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
    

    【讨论】:

      【解决方案7】:

      只是

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

      【讨论】:

        【解决方案8】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-09-20
          • 2019-02-14
          • 1970-01-01
          • 1970-01-01
          • 2018-10-22
          • 2020-03-14
          • 2017-06-19
          • 2013-06-20
          相关资源
          最近更新 更多