2011-09-19 13 views
9

Moje postgres'owy zapytanie brzmi:Jak uzyskać włożona lub wybranego wiersza id w PostgreSQL przy użyciu Pythona

query = """INSERT INTO statustable(value) SELECT '%s' 
       WHERE NOT EXISTS (SELECT id, value FROM statustable 
       WHERE value = '%s') RETURNING id""" % (status, status) 
    cursor_postgres.execute(query) 
    conn_postgres.commit() 
    statusId = cursor_postgres.fetchone()[0] 
    print "statusId" + str(statusId) 

muszę dostać świeżo wstawiony id wartość statusu, jeśli nie robi istnieje, lub wybierz swój identyfikator, jeśli już istnieje. RETURNING id zadusiło to zapytanie, więc musiałem je usunąć, aby przynajmniej zadziałało selektywne wstawianie.

Jakieś wskazówki, jak uzyskać tutaj statusId? W innym przypadku robię Upsert. (Wstaw, jeśli nie istnieje, zaktualizuj inaczej) Tutaj znowu potrzebuję wstawionego lub zaktualizowanego identyfikatora wiersza. (Nie, nie jestem przy użyciu procedur przechowywanych, jeśli to był twój pierwszy pytanie ...)

góry dzięki

+0

Uderza mnie, że najszybszym sposobem na zrobienie tego jest prawdopodobnie wykonanie trzech zapytań (w razie potrzeby transakcji). 1) "SELECT id FROM staticable WHERE value = '% s'"% (status) 2) Jeśli nie zostały zwrócone żadne wiersze, "INSERT INTO staticable (value), '% s'"% (status). 3) "SELECT curval (pk_seq)" cokolwiek pk_seq jest wywoływane jako sekwencja dla twojego klucza głównego id. Ale ponieważ nie jest to tym, o co prosiłeś, nie jest to odpowiedź. –

+0

dzięki za odpowiedź @ed. Infact 2 & 3 może zostać scalony przez 'INSERT INTO staticable (value), '% s' RETURNING id"% (status) 'ponieważ to również zwróci identyfikator, ale szukałem umieszczenia tego wszystkiego w jeden. – jerrymouse

Odpowiedz

10

Nie mogę powiedzieć, że w pełni zrozumieć swoją motywację do nalegając na jednym zapytaniu. Myślę, że najlepiej jest mieć dwa proste pytania:

  1. SELECT id FROM statustable WHERE value = '%s'. To daje identyfikator, jeśli wpis istnieje, w takim przypadku pomiń krok 2;
  2. INSERT INTO statustable(value) VALUES('%s') RETURNING id. To da ci id z nowo utworzonego wpisu.

Na koniec - chociaż nie sprawdziłem, czy jest to problem - fetchone() na całym zatwierdzeniu wygląda nieco podejrzanie.

+0

powtórka @ aix, właśnie to zrobiłem, rozwiąłem moje zapytanie na 2. Moja motywacja do pojedynczego zapytania miała na celu sprawdzenie, czy można to zrobić, ponieważ wydawało się to wykonalne.fetchone() jest używane przez commit, ponieważ RETURNING id doesn ' t return id, jeśli nie został zatwierdzony. (Otrzymałem typ None) – jerrymouse

Powiązane problemy