【问题标题】:How do I get a list of column names from a psycopg2 cursor?如何从 psycopg2 游标中获取列名列表?
【发布时间】:2012-05-02 09:27:48
【问题描述】:

我想要一种直接从所选列名生成列标签的通用方法,并记得看到 python 的 psycopg2 模块支持此功能。

【问题讨论】:

    标签: python psycopg2


    【解决方案1】:

    来自 Mark Lutz 的“Python 编程”:

    curs.execute("Select * FROM people LIMIT 0")
    colnames = [desc[0] for desc in curs.description]
    

    【讨论】:

    • 如果您只需要列名,请不要选择表中的所有行。这样更有效率:curs.execute("SELECT * FROM people LIMIT 0")
    • 值得补充的是,这对视图和表都适用,但从information_schema 获取视图的列名并不(容易)。
    • 获取名称作为属性可能更直观:colnames = [desc.name for desc in curs.description]
    • 需要注意的是,从游标描述函数中读取的列名以小写形式出现。 curs.execute("Select userId FROM people") colnames = [desc[0] for desc in curs.description] assert colnames == ['userid']
    • curs.description 对我来说是无,我不知道为什么......我正在查询 Redshift,如果这有影响的话。
    【解决方案2】:

    您可以做的另一件事是创建一个光标,您可以使用该光标按列的名称引用您的列(这是我首先访问此页面的需要):

    import psycopg2
    from psycopg2.extras import RealDictCursor
    
    ps_conn = psycopg2.connect(...)
    ps_cursor = psql_conn.cursor(cursor_factory=RealDictCursor)
    
    ps_cursor.execute('select 1 as col_a, 2 as col_b')
    my_record = ps_cursor.fetchone()
    print (my_record['col_a'],my_record['col_b'])
    
    >> 1, 2
    

    【讨论】:

    • 请参考资料来源
    • 在我的情况下,“as col_a”是不必要的。我省略了它,光标返回的记录使用了我表中的列名。
    【解决方案3】:

    在单独的查询中获取列名,您可以查询 information_schema.columns 表。

    #!/usr/bin/env python3
    
    import psycopg2
    
    if __name__ == '__main__':
      DSN = 'host=YOUR_DATABASE_HOST port=YOUR_DATABASE_PORT dbname=YOUR_DATABASE_NAME user=YOUR_DATABASE_USER'
    
      column_names = []
    
      with psycopg2.connect(DSN) as connection:
          with connection.cursor() as cursor:
              cursor.execute("select column_name from information_schema.columns where table_schema = 'YOUR_SCHEMA_NAME' and table_name='YOUR_TABLE_NAME'")
              column_names = [row[0] for row in cursor]
    
      print("Column names: {}\n".format(column_names))
    

    获取与数据行相同的查询中的列名,可以使用游标的描述字段:

    #!/usr/bin/env python3
    
    import psycopg2
    
    if __name__ == '__main__':
      DSN = 'host=YOUR_DATABASE_HOST port=YOUR_DATABASE_PORT dbname=YOUR_DATABASE_NAME user=YOUR_DATABASE_USER'
    
      column_names = []
      data_rows = []
    
      with psycopg2.connect(DSN) as connection:
        with connection.cursor() as cursor:
          cursor.execute("select field1, field2, fieldn from table1")
          column_names = [desc[0] for desc in cursor.description]
          for row in cursor:
            data_rows.append(row)
    
      print("Column names: {}\n".format(column_names))
    

    【讨论】:

      【解决方案4】:

      如果你想从 db 查询中获得一个命名元组 obj,你可以使用以下 sn-p:

      from collections import namedtuple
      
      def create_record(obj, fields):
          ''' given obj from db returns named tuple with fields mapped to values '''
          Record = namedtuple("Record", fields)
          mappings = dict(zip(fields, obj))
          return Record(**mappings)
      
      cur.execute("Select * FROM people")
      colnames = [desc[0] for desc in cur.description]
      rows = cur.fetchall()
      cur.close()
      result = []
      for row in rows:
          result.append(create_record(row, colnames))
      

      这使您可以像访问类属性一样访问记录值,即

      record.id、record.other_table_column_name 等

      甚至更短

      from psycopg2.extras import NamedTupleCursor
      with cursor(cursor_factory=NamedTupleCursor) as cur:
         cur.execute("Select * ...")
         return cur.fetchall()
      

      【讨论】:

        【解决方案5】:

        如果您希望获得一个熊猫数据框已经关联了列标题,试试这个:

        import psycopg2, pandas
        
        con=psycopg2.connect(
            dbname=DBNAME, 
            host=HOST, 
            port=PORT, 
            user=USER, 
            password=PASSWORD
        )
        
        sql = """
        select * from x
        """
        
        d = pandas.read_sql_query(sql,con)
        
        con.close()
        
        print(type(d))
        
        print(pandas.DataFrame.head(d))
        

        【讨论】:

        • 这在我看来是最简单的。我很惊讶您必须进行单独的查询才能获取列名。为我工作。
        • 完全同意,@ChuckPedro
        • 最简单的方法。这应该有更多的支持
        • 这是迄今为止最简单的,但速度很慢。最快的方法是使用pd.DataFrame(np.array(cur.fetchall())),它带有一系列数字作为列名。
        【解决方案6】:

        执行SQL查询后,编写2.7编写的python脚本

        total_fields = len(cursor.description)    
        fields_names = [i[0] for i in cursor.description   
            Print fields_names
        

        【讨论】:

          【解决方案7】:

          我注意到您必须在查询后使用cursor.fetchone() 才能获取cursor.description(即[desc[0] for desc in curs.description])中的列列表

          【讨论】:

            【解决方案8】:
             # You can use this function
             def getColumns(cursorDescription):
                 columnList = []
                 for tupla in cursorDescription:
                     columnList.append(tupla[0])
                 return columnList 
            

            【讨论】:

              【解决方案9】:

              我也曾经遇到过类似的问题。我用一个简单的技巧来解决这个问题。 假设您在列表中有列名,例如

              col_name = ['a', 'b', 'c']
              

              然后你可以做以下事情

              for row in cursor.fetchone():
                  print zip(col_name, row)
              

              【讨论】:

                【解决方案10】:
                #!/usr/bin/python
                import psycopg2
                #note that we have to import the Psycopg2 extras library!
                import psycopg2.extras
                import sys
                
                def main():
                    conn_string = "host='localhost' dbname='my_database' user='postgres' password='secret'"
                    # print the connection string we will use to connect
                    print "Connecting to database\n ->%s" % (conn_string)
                
                    # get a connection, if a connect cannot be made an exception will be raised here
                    conn = psycopg2.connect(conn_string)
                
                    # conn.cursor will return a cursor object, you can use this query to perform queries
                    # note that in this example we pass a cursor_factory argument that will
                    # dictionary cursor so COLUMNS will be returned as a dictionary so we
                    # can access columns by their name instead of index.
                    cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
                
                    # tell postgres to use more work memory
                    work_mem = 2048
                
                    # by passing a tuple as the 2nd argument to the execution function our
                    # %s string variable will get replaced with the order of variables in
                    # the list. In this case there is only 1 variable.
                    # Note that in python you specify a tuple with one item in it by placing
                    # a comma after the first variable and surrounding it in parentheses.
                    cursor.execute('SET work_mem TO %s', (work_mem,))
                
                    # Then we get the work memory we just set -> we know we only want the
                    # first ROW so we call fetchone.
                    # then we use bracket access to get the FIRST value.
                    # Note that even though we've returned the columns by name we can still
                    # access columns by numeric index as well - which is really nice.
                    cursor.execute('SHOW work_mem')
                
                    # Call fetchone - which will fetch the first row returned from the
                    # database.
                    memory = cursor.fetchone()
                
                    # access the column by numeric index:
                    # even though we enabled columns by name I'm showing you this to
                    # show that you can still access columns by index and iterate over them.
                    print "Value: ", memory[0]
                
                    # print the entire row 
                    print "Row: ", memory
                
                if __name__ == "__main__":
                    main()
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2012-03-13
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多