Skip to content

타입 시스템 (한국어)

🌐 TYPES.md의 번역입니다. 영어 원문이 표준이며, CI가 영어 원문과의 구조 일치를 검사합니다.

pycubrid의 PEP 249 타입 객체·생성자·CUBRID CCI 데이터 타입 코드의 완전한 참조.


목차


선언 SQL 타입 vs Fetch/Description 타입

이 가이드는 타입 정보의 두 가지 관점을 구분합니다:

  • 선언 SQL 타입은 DDL에서 정의하고 SQL에서 바인딩하는 컬럼 타입입니다 — VARCHAR, JSON, SET, BLOB, TIMESTAMPTZ 등.
  • Fetch/description 타입은 cursor.description[n][1]로 노출되는 CUBRIDDataType 정수 코드와, pycubrid가 와이어 데이터를 디코딩한 후 반환하는 Python 객체입니다.

아래 PEP 249 타입 객체 섹션은 선언 SQL 타입을 표준 DB-API 패밀리로 묶습니다. 이후 섹션은 raw CUBRIDDataType 코드와 fetch 시 반환되는 정확한 Python 값을 나열합니다.


개요

pycubrid는 DB-API 2.0 (PEP 249) 타입 시스템을 다음으로 구현합니다:

  • 타입 객체 5종 — STRING, BINARY, NUMBER, DATETIME, ROWID
  • 생성자 7종 — Date, Time, Timestamp, DateFromTicks, TimeFromTicks, TimestampFromTicks, Binary
  • CCI 데이터 타입 코드 27+종 — CUBRID 와이어 타입을 Python 타입으로 매핑 (JSON·컬렉션 지원 포함)

타입 객체는 cursor.description의 타입 코드와 비교할 수 있습니다:

import pycubrid

conn = pycubrid.connect(host="localhost", port=33000, database="testdb")
cur = conn.cursor()
cur.execute("SELECT name, age, created_at FROM users")

for col in cur.description:
    col_name = col[0]
    col_type = col[1]

    if col_type == pycubrid.STRING:
        print(f"{col_name} is a string column")
    elif col_type == pycubrid.NUMBER:
        print(f"{col_name} is a numeric column")
    elif col_type == pycubrid.DATETIME:
        print(f"{col_name} is a date/time column")

DBAPIType 클래스

DBAPIType 클래스는 PEP 249 타입 비교 프로토콜을 구현합니다. 각 인스턴스는 정수 타입 코드의 frozenset을 감싸며, 그 집합의 모든 코드와 같음 비교됩니다.

from pycubrid.types import DBAPIType

# 커스텀 타입 객체 생성
MY_TYPE = DBAPIType("MY_TYPE", frozenset({1, 2, 3}))

# 정수 타입 코드와 비교
assert MY_TYPE == 1      # True — 1은 집합에 있음
assert MY_TYPE == 4      # False — 4는 집합에 없음
assert MY_TYPE != 4      # True

# 다른 DBAPIType 인스턴스와 비교
OTHER = DBAPIType("OTHER", frozenset({1, 2, 3}))
assert MY_TYPE == OTHER  # True — 같은 값 집합

메서드

메서드 설명
__eq__(other) other(int)가 values에 있거나, other(DBAPIType)가 같은 values 집합을 가지면 True
__ne__(other) __eq__의 부정
__hash__() 값의 frozen 집합 기반 해시
__repr__() DBAPIType('name') 반환

PEP 249 타입 객체

STRING

문자열 기반 컬럼을 기술합니다.

from pycubrid import STRING
멤버 타입 CCI 코드 CUBRID SQL 타입
CHAR 1 CHAR(n)
STRING (VARCHAR) 2 VARCHAR(n)
NCHAR 3 NCHAR(n)
VARNCHAR 4 NCHAR VARYING(n)
ENUM 25 ENUM
CLOB 24 CLOB
JSON 34 JSON

BINARY

바이너리 데이터 컬럼을 기술합니다.

from pycubrid import BINARY
멤버 타입 CCI 코드 CUBRID SQL 타입
BIT 5 BIT(n)
VARBIT 6 BIT VARYING(n)
BLOB 23 BLOB

NUMBER

숫자 컬럼을 기술합니다.

from pycubrid import NUMBER
멤버 타입 CCI 코드 CUBRID SQL 타입 Python 타입
SHORT 9 SMALLINT int
INT 8 INTEGER int
BIGINT 21 BIGINT int
FLOAT 11 FLOAT float
DOUBLE 12 DOUBLE float
NUMERIC 7 NUMERIC(p, s) Decimal
MONETARY 10 MONETARY float

DATETIME

날짜와 시간 컬럼을 기술합니다.

from pycubrid import DATETIME
멤버 타입 CCI 코드 CUBRID SQL 타입 Python 타입
DATE 13 DATE datetime.date
TIME 14 TIME datetime.time
TIMESTAMP 15 TIMESTAMP datetime.datetime
DATETIME 22 DATETIME datetime.datetime
TIMESTAMPTZ 29 TIMESTAMPTZ datetime.datetime
TIMESTAMPLTZ 30 TIMESTAMPLTZ datetime.datetime
DATETIMETZ 31 DATETIMETZ datetime.datetime
DATETIMELTZ 32 DATETIMELTZ datetime.datetime

ROWID

행 식별자 컬럼을 기술합니다.

from pycubrid import ROWID
멤버 타입 CCI 코드 CUBRID SQL 타입 Python 타입
OBJECT 19 OBJECT (OID) str ("OID:@page\|slot\|volume")

PEP 249 생성자

이 함수들은 쿼리 파라미터로 사용할 수 있는 Python 객체를 만듭니다.

생성자 시그니처 반환 설명
Date (year, month, day) datetime.date 달력 날짜
Time (hour, minute, second) datetime.time 시각
Timestamp (year, month, day, hour, minute, second) datetime.datetime 날짜와 시간
DateFromTicks (ticks) datetime.date Unix 타임스탬프로부터 날짜
TimeFromTicks (ticks) datetime.time Unix 타임스탬프로부터 시각
TimestampFromTicks (ticks) datetime.datetime Unix 타임스탬프로부터 datetime
Binary (value) bytes bytes, bytearray, 또는 str(UTF-8)로부터 바이너리 데이터

사용

import pycubrid

# 날짜/시간 생성자
d = pycubrid.Date(2025, 3, 15)
t = pycubrid.Time(14, 30, 0)
ts = pycubrid.Timestamp(2025, 3, 15, 14, 30, 0)

# Unix 타임스탬프로부터
d2 = pycubrid.DateFromTicks(1710500000.0)
t2 = pycubrid.TimeFromTicks(1710500000.0)
ts2 = pycubrid.TimestampFromTicks(1710500000.0)

# 바이너리 생성자
b1 = pycubrid.Binary(b"\x00\x01\x02")           # bytes로부터
b2 = pycubrid.Binary(bytearray([0, 1, 2]))      # bytearray로부터
b3 = pycubrid.Binary("hello")                    # str로부터 → UTF-8 인코딩된 bytes

CUBRID CCI_U_TYPE 코드

이 정수 코드들은 CAS 와이어 프로토콜에서 사용되며 cursor.description[n][1]에 나타납니다.

CUBRIDDataType.NULL은 CUBRIDDataType.UNKNOWN의 별칭입니다(둘 다 0). CUBRIDDataType.NULL is CUBRIDDataType.UNKNOWN이 참이고 CUBRIDDataType(0).name은 "UNKNOWN"입니다.

상수 코드 CUBRID 타입 분류
UNKNOWN / NULL 0 NULL —
CHAR 1 CHAR(n) STRING
STRING 2 VARCHAR(n) STRING
NCHAR 3 NCHAR(n) STRING
VARNCHAR 4 NCHAR VARYING(n) STRING
BIT 5 BIT(n) BINARY
VARBIT 6 BIT VARYING(n) BINARY
NUMERIC 7 NUMERIC(p, s) NUMBER
INT 8 INTEGER NUMBER
SHORT 9 SMALLINT NUMBER
MONETARY 10 MONETARY NUMBER
FLOAT 11 FLOAT NUMBER
DOUBLE 12 DOUBLE NUMBER
DATE 13 DATE DATETIME
TIME 14 TIME DATETIME
TIMESTAMP 15 TIMESTAMP DATETIME
SET 16 SET 컬렉션
MULTISET 17 MULTISET 컬렉션
SEQUENCE 18 SEQUENCE / LIST 컬렉션
OBJECT 19 OBJECT (OID) ROWID
RESULTSET 20 결과 집합 —
BIGINT 21 BIGINT NUMBER
DATETIME 22 DATETIME DATETIME
BLOB 23 BLOB BINARY
CLOB 24 CLOB STRING
ENUM 25 ENUM STRING
JSON 34 JSON STRING
TIMESTAMPTZ 29 TIMESTAMPTZ DATETIME
TIMESTAMPLTZ 30 TIMESTAMPLTZ DATETIME
DATETIMETZ 31 DATETIMETZ DATETIME
DATETIMELTZ 32 DATETIMELTZ DATETIME

이 코드들은 CUBRIDDataType enum으로 사용할 수 있습니다:

from pycubrid.constants import CUBRIDDataType

print(CUBRIDDataType.INT)       # CUBRIDDataType.INT (8)
print(CUBRIDDataType.VARCHAR)   # AttributeError — CUBRIDDataType.STRING (2)을 사용하세요

Fetch 변환 표

fetch 시 pycubrid가 CUBRID 와이어 타입을 Python 객체로 변환하는 방식:

CUBRID 타입 CCI 코드 Python 타입 비고
CHAR, VARCHAR, NCHAR, NCHAR VARYING, ENUM 1–4, 25 str Null 종단, 연결 charset(기본 UTF-8)으로 디코딩; 디코딩할 수 없는 바이트는 코덱 이름을 담은 DataError 발생 (연결은 유지). EUC-KR 데이터베이스에서 CHAR(n)은 U+3000으로 채움
SHORT (SMALLINT) 9 int 16비트 부호 있는 정수
INTEGER 8 int 32비트 부호 있는 정수
BIGINT 21 int 64비트 부호 있는 정수
FLOAT 11 float IEEE 754 단정밀도
DOUBLE, MONETARY 12, 10 float IEEE 754 배정밀도
NUMERIC / DECIMAL 7 Decimal 정확한 숫자 (문자열 파싱)
DATE 13 datetime.date 달력 날짜
TIME 14 datetime.time 시각 (초 정밀도; 바인딩한 datetime.time의 마이크로초와 tzinfo는 오류 없이 버려집니다. 파라미터 바인딩 참고)
TIMESTAMP 15 datetime.datetime 날짜 + 시간 (microsecond = 0)
DATETIME 22 datetime.datetime 날짜 + 시간 + 밀리초
TIMESTAMPTZ, TIMESTAMPLTZ 29, 30 datetime.datetime 타임존 포함 타임스탬프 (초 정밀도, microsecond = 0)
DATETIMETZ, DATETIMELTZ 31, 32 datetime.datetime 타임존 포함 datetime (밀리초 정밀도)
BIT, BIT VARYING 5, 6 bytes raw 바이너리 데이터. 빈 BIT/BIT VARYING 값(X'', B'')은 NULL과 구분되는 b"" (#994). JDBC 드라이버를 따른 동작이며, 공식 CUBRIDdb 드라이버는 X''에 None을 돌려줌
JSON 34 str 또는 Any 기본은 raw JSON 문자열; json_deserializer= 설정 시 디코딩됨. 연결 charset과 무관하게 항상 UTF-8
SET, MULTISET, SEQUENCE 16, 17, 18 bytes 또는 디코딩된 컬렉션 decode_collections=True일 때만 디코딩
OBJECT (OID) 19 str 형식: "OID:@page\|slot\|volume"
BLOB 23 dict LOB 핸들 (아래 참고)
CLOB 24 dict LOB 핸들 (아래 참고); Lob.read()는 charset으로 디코딩하지 않은 컬럼 문자셋의 바이트 반환
NULL / UNKNOWN 0 None —

로컬 타임존 타입: TIMESTAMPLTZ와 DATETIMELTZ 값은 값을 저장할 때의 타임존이 아니라 세션 타임존 기준의 aware datetime으로 반환됩니다. 세션 타임존은 SET TIME ZONE '<zone>'으로 설정합니다. pycubrid 1.8.0부터 CAS 세션이 유지되는 동안에는 commit()/rollback() 이후에도 타임존이 유지됩니다. 트랜잭션 경계 후 CAS가 소켓을 닫으면(CAS 재시작, CHANGE CLIENT, cubrid broker reset) 드라이버가 재연결하고 새 세션은 서버 기본 타임존을 사용하므로, 다른 SQL 세션 상태와 마찬가지로 SET TIME ZONE을 다시 적용해야 합니다(연결 가이드의 "트랜잭션 경계에서 CAS가 재활용되는 경우" 참고). 세션 타임존이 바뀌면 같은 저장 시점(instant)이 다른 UTC 오프셋으로 반환됩니다. TIMESTAMPTZ와 DATETIMETZ는 값 자체의 타임존을 가집니다.

반복되는 DST 시각(#819): 반복되는 벽시계 시각에 있는, 지역 tzinfo (ZoneInfo)를 가진 aware datetime을 바인딩하면 fold가 유지됩니다. fold=0 값은 지역 이름만 있는 리터럴을 유지하며, CUBRID는 이를 첫 번째 발생으로 해석합니다. fold=1이면 pycubrid는 타임존 약어를 덧붙이고 (America/New_York EST), 약어가 숫자이거나 두 발생이 같은 약어를 쓰면 오프셋만 보냅니다. 따라서 두 번째 발생이 더 이상 첫 번째로 저장되지 않습니다. 건너뛴 봄철 시각은 CUBRID가 거부합니다. 파라미터 바인딩을 참고하세요.

0 날짜 (#512): CUBRID는 DATE'0000-00-00', DATETIME'0000-00-00 00:00:00' 및 0 값의 TIMESTAMP, TIMESTAMPTZ, TIMESTAMPLTZ, DATETIMETZ, DATETIMELTZ를 허용하지만 Python datetime에는 0년이 없습니다. 이런 값을 가져오면 execute()에서든 이후 fetch 페이지에서든 CUBRID 타입과 필드 값을 담은 DataError가 발생합니다. 연결은 계속 사용할 수 있으며, 잘못된 UTF-8(#492)과 마찬가지로 커서는 서버 핸들을 유지합니다. 이후 페이지에서 발생한 경우 그 페이지 전에 가져온 행은 그대로 반환되고, 그 뒤의 fetch는 다음 execute() 전까지 같은 DataError를 계속 발생시킵니다(#507). Python이 표현할 수 없는 다른 날짜/시간 필드 값도 같은 방식으로 보고됩니다. None이나 텍스트로 반환하는 옵션은 없으므로 SQL에서 변환하세요. 예: NULLIF(d, DATE'0000-00-00')(0 값은 NULL), CASE WHEN d = DATE'0000-00-00' THEN NULL ELSE d END, TO_CHAR(d, 'YYYY-MM-DD')('0000-00-00' 반환). 명시적 prepared API(pycubrid.compat.native)는 fail-closed로 동작하여 OperationalError를 발생시키고 세션을 폐기합니다. 0 날짜 또는 날짜시간 값을 참고하세요.

타임존 디코딩 (#413): CUBRID는 각 값의 타임존을 텍스트로 보냅니다. 오프셋 (+05:30)이거나, 리전 이름과 그 시점의 약어(Asia/Seoul KST, LTZ 타입은 UTC UTC)입니다. pycubrid는 다음과 같이 해석합니다.

  • 오프셋은 고정 datetime.timezone으로 변환합니다.
  • 리전은 zoneinfo.ZoneInfo(region)으로 변환합니다. 서머타임이 끝나 같은 벽시계 시각이 두 번 나타나면 약어로 fold를 고릅니다. 따라서 2026-11-01 01:30의 America/New_York EST는 UTC-05:00(fold=1), EDT는 UTC-04:00입니다. 약어가 없거나 알 수 없는 경우, 또는 두 시점이 같은 약어를 쓰는 경우 (2014-10-26의 Europe/Moscow MSK)에는 fold=0을 유지합니다.
  • 빈 타임존은 naive datetime으로 반환합니다.

클라이언트의 타임존 데이터베이스가 모르는 리전이나, 형식이 잘못되었거나 ±24시간 범위를 벗어난 오프셋은 naive 값을 조용히 반환하지 않고, 해당 타임존을 담은 DataError를 발생시킵니다. 연결은 계속 사용할 수 있습니다. 명시적 prepared API(pycubrid.compat.native)는 잘못된 UTF-8(#492)과 마찬가지로 fail-closed로 동작하여 OperationalError를 발생시키고 세션을 폐기합니다. zoneinfo는 시스템 데이터베이스 또는 tzdata 패키지를 읽습니다. Windows에서는 pycubrid가 tzdata를 자동으로 설치하며, 최소 구성 Linux 이미지에서는 tzdata를 (pip 또는 OS 패키지로) 설치하세요. TZ 값의 타임존을 해석할 수 없음을 참고하세요.


LOB 타입 처리

LOB 컬럼(BLOB과 CLOB)은 내용으로 반환되지 않습니다. 대신, Lob 클래스와 함께 실제 데이터를 읽을 수 있는 핸들 딕셔너리를 반환합니다.

LOB 핸들 구조

BLOB 또는 CLOB 컬럼을 fetch하면 다음을 받습니다:

{
    "lob_type": 23,                    # CUBRIDDataType.BLOB (23) 또는 CLOB (24)
    "lob_length": 1024,                # LOB 내용의 바이트 크기
    "file_locator": "file://.../...",   # 서버 측 파일 로케이터
    "packed_lob_handle": b"...",        # Lob.read()용 raw 핸들 바이트
}

LOB 내용 읽기

from pycubrid.lob import Lob
from pycubrid.constants import CUBRIDDataType

conn = pycubrid.connect(host="localhost", port=33000, database="testdb")
cur = conn.cursor()

# CLOB 컬럼에 문자열 데이터 직접 삽입
cur.execute("INSERT INTO cookbook_docs (content) VALUES ('Hello, CLOB!')")
conn.commit()

# fetch는 LOB 핸들 dict를 반환, 내용이 아님
cur.execute("SELECT content FROM cookbook_docs WHERE id = 1")
row = cur.fetchone()
lob_handle = row[0]  # lob_type, lob_length 등을 담은 dict

# 내용을 읽으려면 packed 핸들로 Lob 클래스 사용
lob = Lob(conn, CUBRIDDataType.CLOB, lob_handle["packed_lob_handle"])
content = lob.read(lob_handle["lob_length"])
print(content)  # b'Hello, CLOB!'

중요: Lob 객체를 execute()나 기본 executemany()의 쿼리 파라미터로 전달할 수 없습니다. CLOB 컬럼에는 문자열을, BLOB 컬럼에는 바이트를 직접 삽입하세요. 예외는 autocommit이 꺼진 동기 커서의 executemany(..., prepared=True)로, 같은 연결의 Lob을 핸들로 바인딩합니다(API_REFERENCE.md).


컬렉션 타입

CUBRID의 컬렉션 타입(SET, MULTISET, SEQUENCE)은 하위 호환을 위해 기본적으로 raw bytes로 반환됩니다. connect() 또는 pycubrid.aio.connect()에 decode_collections=True를 전달하면, pycubrid는 지원되는 컬렉션 페이로드를 Python 컨테이너로 디코딩합니다.

CUBRID 타입 CCI 코드 decode_collections=False decode_collections=True
SET 16 bytes 해시 가능하면 frozenset, 아니면 tuple
MULTISET 17 bytes list
SEQUENCE 18 bytes list

참고:

  • cursor.description은 요소 타입이 아니라 컬렉션 코드(16, 17, 18)를 반환합니다. 정수 요소는 Python int를 유지하며 MULTISET은 중복, SEQUENCE는 순서를 보존합니다. 동기·비동기 fetch에 동일한 디코딩 규칙이 적용됩니다.
  • description의 마지막 null_ok 필드는 PEP 249 의미로 NULL 허용 컬럼이면 True, NOT NULL/기본키 컬럼이면 False입니다. CAS의 반대 의미 플래그 is_non_null을 그대로 노출하지 않습니다.
  • 모든 요소가 SQL NULL인 비어 있지 않은 컬렉션(예: {NULL}, {NULL, NULL})은 MULTISET/SEQUENCE에서 [None, ...], SET에서 frozenset({None})으로 디코딩됩니다. 빈 컬렉션은 [] / frozenset()으로 디코딩됩니다.
  • 빈 BIT/BIT VARYING 요소(X'', 와이어 길이 0)는 b"", NULL 요소(길이 -1)는 None으로 디코딩되므로 SEQUENCE{X'', NULL, X'01'}은 [b"", None, b"\x01"]입니다(#998). 다른 타입의 길이 0 요소는 None입니다.
  • 중첩 컬렉션 페이로드는 raw bytes로 유지됩니다.
  • 알 수 없는 컬렉션 요소 타입은 raw bytes로 폴백됩니다.
  • SET 값은 모든 디코딩된 요소가 해시 가능하면 frozenset으로 정규화됩니다. 집합에 해시 불가능한 요소가 있으면(예: 디코딩된 JSON 객체), 예외 없이 내용을 보존하기 위해 tuple을 반환합니다.

JSON 컬럼

JSON 컬럼은 CUBRID 타입 코드 34를 사용합니다.

연결 옵션 fetch 결과
기본 (json_deserializer=None) raw JSON str
json_deserializer=json.loads 디코딩된 Python 객체
json_deserializer=custom_callable 콜러블의 반환 값

이 옵트인 동작은 애플리케이션이 JSON 파싱을 지연시키는 것을 선호할 때 fetch를 할당-가볍게 유지합니다.

decode_collections

decode_collections는 pycubrid.connect()와 pycubrid.aio.connect() 양쪽의 연결 수준 스위치입니다.

설정 결과
False (기본) 컬렉션 페이로드를 raw CAS 와이어 bytes로 반환
True 지원되는 SET, MULTISET, SEQUENCE 페이로드를 Python 컨테이너로 디코딩

컬렉션 바인딩

일반 Python set, frozenset, list, tuple 값은 파라미터로 거부됩니다. 컬렉션을 바인딩하려면 원소를 타입 지정 컬렉션 파라미터로 감싸세요(#567):

클래스 렌더링되는 리터럴 서버 의미
pycubrid.types.Set SET{...} 중복 제거, 순서 유지 안 함
pycubrid.types.Multiset MULTISET{...} 중복 유지, 순서 유지 안 함
pycubrid.types.Sequence SEQUENCE{...} (LIST{...}와 같은 타입) 중복과 순서 유지
from pycubrid.types import Multiset, Sequence, Set

cur.execute("INSERT INTO t VALUES (?, ?, ?)", (Set([1, 2]), Multiset(["a", "a"]), Sequence([3, 1])))

이 클래스들은 최상위 pycubrid 패키지에서도 export됩니다. 각각 불변이고, 원소를 tuple(.elements)로 저장하며, 하위 클래스를 만들 수 없습니다. 원소는 스칼라 파라미터와 같은 타입(None, bool, int, float, Decimal, str, bytes, bytearray, date, time, datetime)을 받으며 같은 보호된 렌더러로 렌더링됩니다. 중첩 컬렉션은 ProgrammingError를 발생시킵니다. 동기와 비동기 일반 커서 모두 지원합니다. 파라미터 바인딩을 참고하세요.

세 클래스 모두 dict를 거부합니다(TypeError) — dict를 순회하면 키만 쓰이고 값은 조용히 버려지기 때문입니다. Sequence는 추가로 set/frozenset을 거부합니다(TypeError): 순회 순서가 보장되지 않아 순서가 있는 컬렉션의 원소 순서가 실행마다 달라질 수 있기 때문입니다. Set과 Multiset은 서버 측 의미가 이미 순서를 버리므로 set/frozenset을 그대로 받습니다. 이 인스턴스들은 copy.copy()(항상 같은 객체를 반환), copy.deepcopy()(모든 원소가 그 자체로 불변이면 같은 객체를 반환하고, bytearray처럼 가변인 원소가 있으면 원소까지 독립적으로 복사한 별개의 객체를 반환해 복사본을 변경해도 원본에 되돌아가 영향을 주지 않음), pickle(동등한 인스턴스로 왕복)에 안전하며, 기존 인스턴스에서 __init__을 다시 호출해도 변경할 수 없습니다.

Set, Multiset, Sequence는 pycubrid.types와 pycubrid의 평범한 이름일 뿐 typing의 별칭이 아니지만, 그중 Sequence는 표준 typing/collections.abc 모듈에도 있는 이름입니다. from pycubrid import *를 쓰면 pycubrid의 Set과 Sequence가 스코프에 들어와 같은 방식으로 import한 typing.Set/typing.Sequence(또는 collections.abc.Sequence)를 가립니다. 같은 모듈에서 둘 다 필요하다면 from pycubrid.types import Sequence as CubridSequence처럼 명시적으로 import하거나(또는 pycubrid를 import해서 pycubrid.Sequence로 사용) 하세요.

디코딩은 바뀌지 않습니다: 조회한 컬렉션은 위 표와 같이(decode_collections=True일 때) 일반 Python 컨테이너이며, 이 파라미터 타입이 아닙니다.


사용 예제

cursor.description으로 타입 확인

import pycubrid

conn = pycubrid.connect(host="localhost", port=33000, database="testdb")
cur = conn.cursor()
cur.execute("SELECT * FROM users LIMIT 1")

for col in cur.description:
    name, type_code, _, _, precision, scale, nullable = col
    if type_code == pycubrid.STRING:
        print(f"  {name}: STRING (precision={precision})")
    elif type_code == pycubrid.NUMBER:
        print(f"  {name}: NUMBER (precision={precision}, scale={scale})")
    elif type_code == pycubrid.DATETIME:
        print(f"  {name}: DATETIME")
    elif type_code == pycubrid.BINARY:
        print(f"  {name}: BINARY")
    elif type_code == pycubrid.ROWID:
        print(f"  {name}: ROWID (OID)")
    else:
        print(f"  {name}: type_code={type_code}")

cur.close()
conn.close()

생성자로 파라미터 바인딩

import pycubrid

conn = pycubrid.connect(host="localhost", port=33000, database="testdb")
cur = conn.cursor()

# 파라미터 값으로 PEP 249 생성자 사용
cur.execute(
    "INSERT INTO cookbook_events (event_date, event_time, created_at) VALUES (?, ?, ?)",
    [
        pycubrid.Date(2025, 12, 25),
        pycubrid.Time(10, 0, 0),
        pycubrid.Timestamp(2025, 3, 15, 14, 30, 0),
    ],
)
conn.commit()
cur.close()
conn.close()

Decimal 파라미터

Decimal 파라미터는 고정소수점 리터럴(E 표기 사용 안 함)로 전송되므로 CUBRID가 작성된 scale 그대로 NUMERIC으로 유지합니다. Decimal("0.0000001")은 float가 아니라 Decimal로 조회됩니다. 고정소수점 리터럴이 CUBRID NUMERIC 최대 정밀도인 38자리를 넘는 값은 DOUBLE이 되지 않고 DataError를 발생시킵니다. 파라미터 바인딩: Decimal 파라미터를 참고하세요.

from decimal import Decimal

cur.execute("SELECT ?", [Decimal("0.0000001")])  # 0.0000001로 전송
assert cur.fetchone()[0] == Decimal("0.0000001")
assert cur.description[0][1] == pycubrid.constants.CUBRIDDataType.NUMERIC

CUBRIDDataType enum 사용

from pycubrid.constants import CUBRIDDataType

# 특정 타입 코드 확인
assert CUBRIDDataType.INT == 8
assert CUBRIDDataType.STRING == 2
assert CUBRIDDataType.DATETIME == 22

# 타입 분기 로직에 사용
def describe_type(code: int) -> str:
    match code:
        case CUBRIDDataType.INT | CUBRIDDataType.BIGINT | CUBRIDDataType.SHORT:
            return "integer"
        case CUBRIDDataType.FLOAT | CUBRIDDataType.DOUBLE:
            return "floating point"
        case CUBRIDDataType.NUMERIC:
            return "exact decimal"
        case CUBRIDDataType.STRING | CUBRIDDataType.CHAR:
            return "text"
        case _:
            return f"other ({code})"

참고: API 참조 · 예제 · 연결 가이드