2014-06-26 8 views
18

Obecnie mam następującą metodę do wykonania wkładania/UPDATE/DELETE przy użyciu psycopg2 w Python:Jak mogę uzyskać liczbę wierszy, których dotyczy problem, od psycopg2 connection.commit()?

def exec_statement(_cxn, _stmt): 
    try: 
     db_crsr = _cxn.cursor() 
     db_crsr.execute(_stmt) 
     _cxn.commit() 
     db_crsr.close() 
     return True 
    except: 
     return False 

Ale to, co naprawdę chciałbym to zrobić, zamiast bool jest powrót wiersz Liczba dotkniętych transakcja lub -1, jeśli operacja się nie powiedzie.

Czy istnieje sposób na uzyskanie liczby wierszy, na które ma wpływ _cxn.commit()? Na przykład. dla pojedynczego INSERT będzie zawsze 1, dla DELETE lub UPDATE, liczba wierszy, których dotyczy instrukcja itp.?

Odpowiedz

31

commit() nie może być używany, aby uzyskać liczbę wierszy, ale można użyć kursor aby uzyskać tę informację po każdym execute rozmowy. Można używać jej atrybut rowcount aby uzyskać liczbę wierszy dla SELECT, INSERT, UPDATE i DELETE.

tj

db_crsr = _cxn.cursor() 
    db_crsr.execute(_stmt) 

    rowcount = db_crsr.rowcount 

    _cxn.commit() 
    db_crsr.close() 

    return rowcount 

Jeśli chcesz powrócić liczbę wierszy, polecam nie łapania żadnych wyjątków, ponieważ jeśli operacja naprawdę nie powiodło się (powiedzieć zapytanie było zniekształcone, było ograniczenie FK naruszenie, itp.), należy podnieść wyjątek, aw takim przypadku osoba dzwoniąca może to złapać i zachowywać się zgodnie z oczekiwaniami. (Lub, jeśli chcą scentralizować obsługę wyjątków, chyba raise zwyczaj MyPostgresException lub podobne).

-1 mogą zostać zwrócone w przypadku awarii niż w niektórych sytuacjach (http://initd.org/psycopg/docs/cursor.html#cursor.rowcount), więc polecam przeciwko używaniu tej wartości jako wskaźnika awarii. Jeśli naprawdę chcesz zwrócić wartość liczbową w przypadku niepowodzenia, być może zwróci się liczba podobna do -10 (w bloku except), ponieważ rowcount nie powinna nigdy tego zwracać.

+0

Podajesz uzasadnione powody, aby nie wychwytywać wyjątków, ale czy istnieje powód, że 'db_crsr.close()' nie znajduje się w bloku 'finally'? Po zakończeniu metody wykracza ono poza zakres. – jpmc26

+0

@ jpmc26: Nie. To było z oryginalnego kodu OP i nie skupiałem się na tym aspekcie. W tym konkretnym przypadku prawdopodobnie zadeklarowałbym * kursor * w bloku 'with', aby automatycznie się zamknął. – khampson

+0

Głupi mnie. Zapominanie 'z'. =) Potrzebuję więcej Pythona w moim życiu. – jpmc26

Powiązane problemy