簡単なサンプルで、、、
まずは、Session使用メソッドの呼び出し側で捕捉
from sqlalchemy import create_engine, text from sqlalchemy.orm import Session
# 接続情報、username, password, host, port, dbname は設定済 engine = create_engine(f'postgresql://{username}:{password}@{host}:{port}/{dbname}') def countquery() -> int: with Session(autocommit=False, autoflush=True, bind=engine) as session: print("---session---") sql = 'SELECT COUNT(*) FROM samples' rows = session.execute(text(sql)) return list(rows)[0][0] if __name__ == '__main__': print("---START---") try: c = countquery() print('count = %d' % c) except Exception as e: print(e) else: print("OK") finally: print("---END---")
正常時
---START--- ---session--- count = 6 OK ---END---
DB接続異常時
---START--- ---session--- (psycopg2.OperationalError) connection to server at "localhost" (::1), port 5432 failed: Connection refused (0x0000274D/10061) Is the server running on that host and accepting TCP/IP connections? connection to server at "localhost" (127.0.0.1), port 5432 failed: Connection refused (0x0000274D/10061) Is the server running on that host and accepting TCP/IP connections? (Background on this error at: https://sqlalche.me/e/20/e3q8) ---END---
これが示しているのは
with Session(autocommit=False, autoflush=True, bind=engine) as session:
の後の session の execute で実行してから接続エラーを検出していることである。
SQLの誤り
---START--- ---session--- (psycopg2.errors.UndefinedTable) リレーション"asamples"は存在しません LINE 1: SELECT COUNT(*) FROM asamples ^ [SQL: SELECT COUNT(*) FROM asamples] (Background on this error at: https://sqlalche.me/e/20/f405) ---END---
今度は、with Session ~ の中で、try-catch を書いてみる。
engine = create_engine(f'postgresql://{username}:{password}@{host}:{port}/{dbname}') def countquery() -> int: with Session(autocommit=False, autoflush=True, bind=engine) as session: print("---session---") try: sql = 'SELECT COUNT(*) FROM samples' rows = session.execute(text(sql)) except Exception as e: print(e) raise else: return list(rows)[0][0] if __name__ == '__main__': print("---START---") c = countquery() print('count = %d' % c) print("---END---")
except Exception: でraise 実行しているので、呼び出し側では try-catch を書かなければ、
呼び出し側に戻ることなく、そこで異常終了になる。