Wie erhalte ich eine Liste mit Spaltennamen von einem psycopg2-Cursor?

136

Ich möchte eine allgemeine Möglichkeit, Spaltenbeschriftungen direkt aus den ausgewählten Spaltennamen zu generieren, und erinnere mich daran, dass das psycopg2-Modul von Python diese Funktion unterstützt.

Setjmp
quelle

Antworten:

224

Aus "Programming Python" von Mark Lutz:

curs.execute("Select * FROM people LIMIT 0")
colnames = [desc[0] for desc in curs.description]
Setjmp
quelle
64
Wenn Sie nur die Spaltennamen möchten, wählen Sie nicht alle Zeilen in der Tabelle aus. Dies ist effizienter:curs.execute("SELECT * FROM people LIMIT 0")
Demitri
2
Es kann sinnvoll sein, hinzuzufügen, dass dies sowohl für Ansichten als auch für Tabellen funktioniert, während es (leicht) nicht möglich ist, Spaltennamen für Ansichten abzurufen information_schema.
wjv
5
Könnte intuitiver sein, um den Namen als Attribut zu erhalten: colnames = [desc.name für desc in curs.description]
rovyko
Es ist wichtig zu beachten, dass Spaltennamen, die aus der Cursorbeschreibungsfunktion gelesen werden, in Kleinbuchstaben angezeigt werden. curs.execute("Select userId FROM people") colnames = [desc[0] for desc in curs.description] assert colnames == ['userid']
Dyltini
Sie sollten Ihre Antwort mit dem Vorschlag LIMIT 0 aktualisieren. Andernfalls rufen Sie die gesamte Tabelle ab, um die Namen zu überprüfen.
Carlos Pinzón
40

Sie können auch einen Cursor erstellen, mit dem Sie Ihre Spalten anhand ihrer Namen referenzieren können (dies hat mich zunächst zu dieser Seite geführt):

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
quelle
26

Um die Spaltennamen in einer separaten Abfrage abzurufen , können Sie die Tabelle information_schema.columns abfragen.

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

Um Spaltennamen in derselben Abfrage wie Datenzeilen abzurufen , können Sie das Beschreibungsfeld des Cursors verwenden:

#!/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
quelle
16

Wenn Sie ein benanntes Tupelobjekt aus der Datenbankabfrage haben möchten, können Sie das folgende Snippet verwenden:

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

Auf diese Weise können Sie auf Datensatzwerte zugreifen, als wären sie Klasseneigenschaften, d. H.

record.id, record.other_table_column_name usw.

oder noch kürzer

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

Nach dem Ausführen der SQL-Abfrage schreiben Sie das folgende in 2.7 geschriebene Python-Skript

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

Ich habe festgestellt, dass Sie cursor.fetchone()nach der Abfrage verwenden müssen, um die Liste der Spalten in cursor.description(dh in [desc[0] for desc in curs.description]) zu erhalten.

user2618351
quelle
0

Ich hatte auch ähnliche Probleme. Ich benutze einen einfachen Trick, um dies zu lösen. Angenommen, Sie haben Spaltennamen in einer Liste wie

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

Dann können Sie Folgendes tun

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