asyncpg
: PostgreSQL과 Python/asyncio를 위해 특별히 설계된 데이터베이스 인터페이스 라이브러리
- Python 3.8 이상 필요, PostgreSQL 버전 9.5부터 17까지 지원
- 다른 PostgreSQL 버전이나 PostgreSQL 프로토콜을 구현하는 다른 데이터베이스도 작동할 수 있지만, 현재는 적극적으로 테스트되지 않음
1. PostgreSQL 연결
1-1. asyncpg 설치
pip install asyncpg
1-2. asyncpg 연결
`asyncpg.connect()` : PostgreSQL 서버에 연결을 설정하는 코루틴
- 연결 매개변수는 연결 URI(dsn) 형식으로 지정하거나, 구체적인 키워드 인수로 지정
async connect(dsn=None, *, host=None, port=None,
user=None, password=None, passfile=None, database=None,
loop=None, timeout=60, statement_cache_size=100,
max_cached_statement_lifetime=300, max_cacheable_statement_size=15360,
command_timeout=None, ssl=None, direct_tls=None,
connection_class=<class 'asyncpg.connection.Connection'>,
record_class=<class 'asyncpg.Record'>, server_settings=None,
target_session_attrs=None, krbsrvname=None, gsslib=None)
매개변수
1. dsn
: 연결 인수를 단일 문자열로 지정한 libpq 연결 URI 형식
postgres://user:password@host:port/database?option=value
<주의>
- URI는 유효해야 함
- 모든 구성 요소는 `urllib.parse.quote_plus()`로 올바르게 인코딩되어야 함
- 리터럴 IPv6 주소는 [대괄호]로 묶어야 함
- e.g. `postgres://dbuser@[fe80::1ff:fe23:4567:890a%25eth0]/dbname`
2. host
: 데이터베이스 서버에 연결할 호스트 주소
- IP 주소, 도메인 이름, Unix 도메인 소켓 디렉토리 경로 지정
- 지정하지 않으면,
- dsn에서 파싱된 값
- PGHOST 환경 변수 값
- Unix의 경우 일반적으로 사용하는 PostgreSQL Unix 도메인 소켓 디렉토리들이 순차적으로 시도
- 마지막으로 "localhost" 시도
3. port
: 서버 호스트에 연결할 포트 번호
- Unix 도메인 소켓 파일 확장자도 포트로 사용할 수 있음
- 지정하지 않으면,
- dsn에서 파싱된 값
- PGPORT 환경 변수 값
- 기본값인 5432 사용
4. user
: 인증에 사용되는 데이터베이스 역할의 이름
- 지정하지 않으면,
- dsn에서 파싱된 값
- PGUSER 환경 변수 값
- 운영 체제에서 실행 중인 애플리케이션의 사용자 이름 사용
5. database
: 연결할 데이터베이스의 이름
- 지정하지 않으면,
- dsn에서 파싱된 값
- PGDATABASE 환경 변수 값
- user 인수에서 계산된 값 사용
6. password
: 서버가 인증을 요구하는 경우 사용할 비밀번호
- 지정하지 않으면,
- dsn에서 파싱된 값
- PGPASSWORD 환경 변수 값 사용
- 환경 변수 사용은 권장 X, 대신 passfile 사용
반환 값
- 새로운 Connection 객체
e.g. PostgreSQL 서버에 연결하여 pg_type 테이블에서 모든 레코드 조회
import asyncpg
import asyncio
async def run():
con = await asyncpg.connect(user='postgres')
types = await con.fetch('SELECT * FROM pg_type')
print(types)
asyncio.run(run())
1-3. asyncpg 연결 해제
`async close(*, timeout=None)` : 연결을 정상적으로 종료
매개변수
- timeout (float): (선택사항) 연결 종료를 위한 제한 시간(초 단위)
2. 예제
import asyncio
import asyncpg
import datetime
async def main():
# Establish a connection to an existing database named "test"
# as a "postgres" user.
conn = await asyncpg.connect('postgresql://postgres@localhost/test')
# Execute a statement to create a new table.
await conn.execute('''
CREATE TABLE users(
id serial PRIMARY KEY,
name text,
dob date
)
''')
# Insert a record into the created table.
await conn.execute('''
INSERT INTO users(name, dob) VALUES($1, $2)
''', 'Bob', datetime.date(1984, 3, 1))
# Select a row from the table.
row = await conn.fetchrow(
'SELECT * FROM users WHERE name = $1', 'Bob')
# *row* now contains
# asyncpg.Record(id=1, name='Bob', dob=datetime.date(1984, 3, 1))
# Close the connection.
await conn.close()
asyncio.run(main())
- 데이터베이스와의 상호작용은 일반적으로 `connect()` 호출로 시작
- 새로운 데이터베이스 세션 설정
- 쿼리를 실행하고 트랜잭션을 관리하는 메서드를 제공하는 새로운 Connection 인스턴스를 반환
asyncpg는 쿼리 인수에 대해 PostgreSQL의 기본 문법인 `$n`을 사용
타입 변환
asyncpg는 PostgreSQL의 데이터 타입을 자동으로 대응되는 Python 타입으로 변환
PostgreSQL Type | Python Type |
anyarray | list |
anyenum | str |
anyrange | asyncpg.Range, tuple |
anymultirange | list[asyncpg.Range ], list[tuple ] 1 |
record | asyncpg.Record, tuple, Mapping |
bit, varbit | asyncpg.BitString |
bool | bool |
box | asyncpg.Box |
bytea | bytes |
char, name, varchar, text, xml | str |
cidr | ipaddress.IPv4Network, ipaddress.IPv6Network |
inet | ipaddress.IPv4Interface, ipaddress.IPv6Interface, ipaddress.IPv4Address, ipaddress.IPv6Address 2 |
macaddr | str |
circle | asyncpg.Circle |
date | datetime.date |
time | offset-naïve datetime.time |
time with time zone | offset-aware datetime.time |
timestamp | offset-naïve datetime.datetime |
timestamp with time zone | offset-aware datetime.datetime |
interval | datetime.timedelta |
float, double precision | float 3 |
smallint, integer, bigint | int |
numeric | Decimal |
json, jsonb | str |
line | asyncpg.Line |
lseg | asyncpg.LineSegment |
money | str |
path | asyncpg.Path |
point | asyncpg.Point |
polygon | asyncpg.Polygon |
uuid | uuid.UUID |
tid | tuple |
<참고> 부동소수점 타입은 파이썬의 부동소수점 값으로 디코딩될 때 정확히 일치하지 않을 수 있음
- 이는 제한된 정밀도의 부동소수점 타입의 구현에 기인한 것
- 진수 표현이 일치해야 할 경우, 쿼리에서 double 또는 numeric으로 형변환을 수행
참고 문서
'Python > Study' 카테고리의 다른 글
[Python] Snap7 ─ Siemens S7 PLC 통신 라이브러리 (0) | 2024.11.22 |
---|---|
[Python] asyncpg 비동기 함수 정리 (2) | 2024.11.21 |
[Python] asyncio ─ 비동기 방식 (1) | 2024.11.18 |