Bagaimana cara saya mendapatkan daftar nama kolom dari kursor psycopg2?

137

Saya ingin cara umum untuk membuat label kolom langsung dari nama kolom yang dipilih, dan ingat melihat modul psycopg2 python mendukung fitur ini.

Setjmp
sumber

Jawaban:

225

Dari "Programming Python" oleh Mark Lutz:

curs.execute("Select * FROM people LIMIT 0")
colnames = [desc[0] for desc in curs.description]
Setjmp
sumber
64
Jika Anda hanya ingin nama kolom, jangan pilih semua baris di tabel. Ini lebih efisien:curs.execute("SELECT * FROM people LIMIT 0")
Demitri
2
Mungkin perlu menambahkan bahwa ini berfungsi untuk tampilan dan juga tabel, sedangkan tidak mudah untuk mendapatkan nama kolom untuk tampilan information_schema.
wjv
5
Mungkin lebih intuitif untuk mendapatkan nama sebagai atribut: colnames = [desc.name for desc in curs.description]
rovyko
Penting untuk dicatat bahwa nama kolom yang dibaca dari fungsi deskripsi kursor keluar dalam huruf kecil. curs.execute("Select userId FROM people") colnames = [desc[0] for desc in curs.description] assert colnames == ['userid']
dyltini
Anda harus memperbarui jawaban Anda dengan saran LIMIT 0. Kalau tidak, Anda akan mengambil seluruh tabel hanya untuk memeriksa nama.
Carlos Pinzón
41

Hal lain yang dapat Anda lakukan adalah membuat kursor yang dapat digunakan untuk mereferensikan kolom Anda dengan namanya (itulah kebutuhan yang membuat saya menuju halaman ini sejak awal):

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
Dennis
sumber
26

Untuk mendapatkan nama kolom dalam kueri yang terpisah , Anda dapat meminta tabel 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))

Untuk mendapatkan nama kolom dalam kueri yang sama dengan baris data , Anda bisa menggunakan bidang deskripsi kursor:

#!/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))
bitek
sumber
16

Jika Anda ingin memiliki tuple obj bernama dari permintaan db Anda dapat menggunakan potongan berikut:

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

Ini memungkinkan Anda untuk mengakses nilai rekaman seolah-olah mereka adalah properti kelas yaitu

record.id, record.other_table_column_name, dll.

atau bahkan lebih pendek

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

Setelah mengeksekusi query SQL, tulis skrip python berikut yang ditulis dalam 2.7

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

Saya perhatikan bahwa Anda harus menggunakan cursor.fetchone()setelah permintaan untuk mendapatkan daftar kolom di cursor.description(yaitu di [desc[0] for desc in curs.description])

pengguna2618351
sumber
0

Saya juga terbiasa menghadapi masalah serupa. Saya menggunakan trik sederhana untuk menyelesaikan ini. Misalkan Anda memiliki nama kolom dalam daftar suka

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

Maka Anda bisa melakukan hal berikut

for row in cursor.fetchone():
    print zip(col_name, row)
pengguna2925213
sumber
0
 # You can use this function
 def getColumns(cursorDescription):
     columnList = []
     for tupla in cursorDescription:
         columnList.append(tupla[0])
     return columnList 
Francis Fulgencio
sumber
-7
#!/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()
Ajay Menon
sumber