2016-08-08 27 views
2

Ich versuche, Tabellenname für Feld in Ergebnismenge, die ich aus der Datenbank (Python, Postgres) bekam. Es gibt eine Funktion in PHP, um den Tabellennamen für das Feld zu erhalten, ich habe es benutzt und es funktioniert, so dass ich weiß, dass es getan werden kann (in PHP). Ich suche nach einer ähnlichen Funktion in Python.Get Tabellenname für Feld in der Datenbank Ergebnis in Python (PostgreSQL)

pg_field_table() Funktion in PHP erhält Ergebnisse und Feldnummer und "gibt den Namen der Tabelle zurück, zu der das Feld gehört". Genau das brauche ich, aber in Python.

Einfache exaple - Erstellen von Tabellen, Zeilen einfügen, wählen Sie Daten:

CREATE TABLE table_a (
    id INT, 
    name VARCHAR(10) 
); 

CREATE TABLE table_b (
    id INT, 
    name VARCHAR(10) 
); 

INSERT INTO table_a (id, name) VALUES (1, 'hello'); 
INSERT INTO table_b (id, name) VALUES (1, 'world'); 

Bei der Verwendung von psycopg2 oder sqlalchemy I richtige Daten und rechte Feldnamen aber ohne Informationen über Tabellen Namen.

import psycopg2 

query = ''' 
    SELECT * 
    FROM table_a A 
    LEFT JOIN table_b B 
     ON A.id = B.id 
''' 

con = psycopg2.connect('dbname=testdb user=postgres password=postgres') 
cur = con.cursor() 
cur.execute(query) 

data = cur.fetchall() 
print('fields', [desc[0] for desc in cur.description]) 
print('data', data) 

Im obigen Beispiel werden Feldnamen gedruckt. Die Ausgabe lautet:

fields ['id', 'name', 'id', 'name'] 
data [(1, 'hello', 1, 'world')] 

Ich weiß, dass es cursor.description, aber es spielt keine Tabellennamen enthält, nur die Feldnamen.

Was ich brauche - eine Möglichkeit zum Abrufen von Tabellennamen für Felder in der Ergebnismenge bei der Verwendung von Raw SQL zum Abfragen von Daten.

EDIT 1: Ich brauche, wenn "Hallo" von "TABLE_A" kam zu wissen, oder "Table_B" werden beide Felder denselben Namen ("name"). Ohne Angabe des Tabellennamens können Sie nicht feststellen, in welcher Tabelle der Wert ist.

EDIT 2: Ich weiß, dass einige Workarounds wie SQL-Aliase gibt es: SELECT table_a.name AS name1, table_b.name AS name2 aber ich bin wirklich fragen, wie Tabellennamen aus Ergebnismenge abzurufen.

EDIT 3: Ich bin für Lösung, die mir keine rohe SQL-Abfrage, manchmal SELECT *, manchmal und nach, dass die Abfrage ausgeführt ich bekomme Feldnamen und Tabellennamen für die Felder in der Ergebnismenge zu schreiben.

+1

Sie bereits die Tabellennamen wussten, wenn Sie die Abfrage liefen. – e4c5

+0

Verwenden Sie SQL-Aliase – polku

+0

Sie können einige Informationen von 'erklären (verbose) ' am Knoten 'Output' erhalten. In Ihrem Beispiel könnte die Ausgabe lauten: "Ausgabe: A.id, A.name, B.id, B.name". Verwenden Sie die 'format' Option, um die Informationen im gewünschten Format zu erhalten:' explain (verbose, format json) ... 'zum Beispiel. Aber wie wäre es mit komplexeren Abfragen wie 'Select greatest (A.name, B.name) als Name aus ...' wo die Quelltabelle für jede Zeile verschieden sein kann? – Abelisto

Antwort

1

Es ist notwendig, die pg_attribute catalog für die Tabelle qualifizierten Spaltennamen abfragen:

query = ''' 
    select 
     string_agg(format(
      '%%1$s.%%2$s as "%%1$s.%%2$s"', 
      attrelid::regclass, attname 
     ) , ', ') 
    from pg_attribute 
    where attrelid = any (%s::regclass[]) and attnum > 0 and not attisdropped 
''' 

cursor.execute(query, ([t for t in ('a','b')],)) 
select_list = cursor.fetchone()[0] 

query = ''' 
    select {} 
    from a left join b on a.id = b.id 
'''.format(select_list) 

print cursor.mogrify(query) 
cursor.execute(query) 
print [desc[0] for desc in cursor.description] 

Ausgang:

select a.id as "a.id", a.name as "a.name", b.id as "b.id", b.name as "b.name" 
    from a left join b on a.id = b.id 

['a.id', 'a.name', 'b.id', 'b.name'] 
+0

Vielen Dank für Ihre Antwort. Ihre Lösung ist für SELECT * konzipiert. Ich suche nach einer Lösung, die es mir erlaubt, eine rohe SQL-Abfrage auszuführen, bei der ich die Spalten angeben muss, die ich abrufen möchte (nach SELECT). Dann erwarte ich nach dem Ausführen der Abfrage nur ausgewählte Felder in der Ergebnismenge mit Feldnamen und Tabellennamen. – dwich

+0

@dwich 'select *' ist das, wonach du gefragt hast –

+0

Du hast Recht, ich habe im obigen Beispiel SELECT * verwendet.Ich suche jedoch nach einer Lösung, die es mir erlaubt, beliebige SQL - SELECT * - oder Listenfelder zu verwenden, die ich abrufen möchte (und dann herauszufinden, aus welcher Tabelle diese Felder stammen). Ich habe die Frage aktualisiert (EDIT 3). – dwich