기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
Go용 Amazon QLDB 드라이버 — 퀵 스타트 튜토리얼
중요
지원 종료 알림: 기존 고객은 2025년 7월 31일 지원이 종료될 QLDB 때까지 Amazon을 사용할 수 있습니다. 자세한 내용은 아마존 QLDB 원장을 Amazon Aurora SQL Postgre로 마이그레이션을
이 자습서에서는 Go용 Amazon QLDB 드라이버의 최신 버전을 사용하여 간단한 애플리케이션을 설정하는 방법을 알아봅니다. 이 안내서에는 드라이버 설치 단계와 기본 create, read, update, delete (CRUD) 작업의 단축 코드 예제가 포함되어 있습니다.
주제
사전 조건
시작하기 전에 다음을 수행해야 합니다.
-
아직 Go 드라이버에 대한 사전 조건을 완료하지 않은 경우, 완료하세요. 여기에는 가입 AWS, 개발을 위한 프로그래밍 방식 액세스 권한 부여, Go 설치가 포함됩니다.
-
quick-start
라는 명칭의 원장을 생성합니다.원장 생성 방법을 알아보려면 콘솔 시작하기의 Amazon QLDB 원장의 기본 작업 또는 1단계: 새 원장 생성 섹션을 참조하세요.
1단계: 드라이버 설치
프로젝트에서 Go 모듈
프로젝트 디렉터리에 다음 go get
명령을 입력합니다.
$
go get -u github.com/awslabs/amazon-qldb-driver-go/v3/qldbdriver
드라이버를 설치하면 AWS SDK for Go v2
2단계: 패키지 가져오기
다음 패키지를 가져오세요. AWS
import ( "context" "fmt" "github.com/amzn/ion-go/ion" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/qldbSession" "github.com/awslabs/amazon-qldb-driver-go/v3/qldbdriver" )
3단계: 드라이버 초기화
quick-start
라는 명칭의 원장에 연결되는 드라이버의 인스턴스를 초기화합니다.
cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { panic(err) } qldbSession := qldbsession.NewFromConfig(cfg, func(options *qldbsession.Options) { options.Region = "
us-east-1
" }) driver, err := qldbdriver.New( "quick-start", qldbSession, func(options *qldbdriver.DriverOptions) { options.LoggerVerbosity = qldbdriver.LogInfo }) if err != nil { panic(err) } defer driver.Shutdown(context.Background())
참고
이 코드 예제에서는 다음을 대체합니다.us-east-1
원장을 생성한 AWS 리전
곳으로 바꾸세요.
4단계: 테이블 및 인덱스 생성
다음 코드 예에서는 CREATE TABLE
및 CREATE
INDEX
문을 실행하는 방법을 보여줍니다.
_, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { _, err := txn.Execute("CREATE TABLE People") if err != nil { return nil, err } // When working with QLDB, it's recommended to create an index on fields we're filtering on. // This reduces the chance of OCC conflict exceptions with large datasets. _, err = txn.Execute("CREATE INDEX ON People (firstName)") if err != nil { return nil, err } _, err = txn.Execute("CREATE INDEX ON People (age)") if err != nil { return nil, err } return nil, nil }) if err != nil { panic(err) }
이 코드는 People
이라는 테이블을 만들고 해당 테이블의 age
및 firstName
필드를 인덱싱합니다. 인덱스는 쿼리 성능을 최적화하고 낙관적 동시성 제어 () OCC 충돌 예외를 제한하는 데 필요합니다.
5단계: 문서 삽입
다음 코드 예에서는 INSERT
문을 실행하는 방법을 보여줍니다. QLDBPartiQL 쿼리 언어 SQL (호환 가능) 및 Amazon Ion 데이터 형식 (상위 세트) 을 지원합니다. JSON
리터럴 PartiQL 사용
다음 코드는 문자열 리터럴 PartiQL 명령문을 사용하여 People
테이블에 문서를 삽입합니다.
_, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("INSERT INTO People {'firstName': 'Jane', 'lastName': 'Doe', 'age': 77}") }) if err != nil { panic(err) }
Ion 데이터 유형 사용
Go의 내장 JSON패키지와
-
다음과 같이
Person
이라는 이름의 Go 구조가 있는 경우.type Person struct { FirstName string `ion:"firstName"` LastName string `ion:"lastName"` Age int `ion:"age"` }
-
Person
의 인스턴스를 만듭니다.person := Person{"John", "Doe", 54}
드라이버는 Ion 인코딩된
person
의 텍스트 표현을 자동으로 마샬링합니다.중요
마샬링과 마샬링 취소가 제대로 작동하려면 Go 데이터 구조의 필드 이름을 내보내야 합니다(첫 글자를 대문자로 표시).
-
person
인스턴스를 트랜잭션의Execute
메서드로 전달합니다._, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("INSERT INTO People ?", person) }) if err != nil { panic(err) }
이 예에서는 물음표(
?
)를 변수 자리 표시자로 사용하여 문서 정보를 해당 문에 전달합니다. 자리 표시자를 사용할 때는 Ion 인코딩된 텍스트 값을 전달해야 합니다.
6단계: 문서 쿼리
다음 코드 예에서는 SELECT
문을 실행하는 방법을 보여줍니다.
p, err := driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { result, err := txn.Execute("SELECT firstName, lastName, age FROM People WHERE age = 54") if err != nil { return nil, err } // Assume the result is not empty hasNext := result.Next(txn) if !hasNext && result.Err() != nil { return nil, result.Err() } ionBinary := result.GetCurrentData() temp := new(Person) err = ion.Unmarshal(ionBinary, temp) if err != nil { return nil, err } return *temp, nil }) if err != nil { panic(err) } var returnedPerson Person returnedPerson = p.(Person) if returnedPerson != person { fmt.Print("Queried result does not match inserted struct") }
이 예제에서는 People
테이블에서 문서를 쿼리하고 결과 세트가 비어 있지 않다고 가정하고 결과에서 문서를 반환합니다.
7단계: 문서 업데이트
다음 코드 예에서는 UPDATE
문을 실행하는 방법을 보여줍니다.
person.Age += 10 _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("UPDATE People SET age = ? WHERE firstName = ?", person.Age, person.FirstName) }) if err != nil { panic(err) }
8단계: 업데이트된 문서 쿼리
다음 코드 예제는 firstName
으로 People
테이블을 쿼리하고 결과 세트의 모든 문서를 반환합니다.
p, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { result, err := txn.Execute("SELECT firstName, lastName, age FROM People WHERE firstName = ?", person.FirstName) if err != nil { return nil, err } var people []Person for result.Next(txn) { ionBinary := result.GetCurrentData() temp := new(Person) err = ion.Unmarshal(ionBinary, temp) if err != nil { return nil, err } people = append(people, *temp) } if result.Err() != nil { return nil, result.Err() } return people, nil }) if err != nil { panic(err) } var people []Person people = p.([]Person) updatedPerson := Person{"John", "Doe", 64} if people[0] != updatedPerson { fmt.Print("Queried result does not match updated struct") }
9단계: 테이블 삭제
다음 코드 예에서는 DROP TABLE
문을 실행하는 방법을 보여줍니다.
_, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("DROP TABLE People") }) if err != nil { panic(err) }
전체 애플리케이션 실행
다음 코드 예는 애플리케이션의 전체 버전입니다. 이전 단계를 개별적으로 수행하는 대신 이 코드 예를 처음부터 끝까지 복사하여 실행할 수도 있습니다. 이 애플리케이션은 이름이 지정된 원장에 대한 몇 가지 기본 CRUD 작업을 보여줍니다. quick-start
참고
이 코드를 실행하기 전에 quick-start
원장에 People
이라는 명칭의 활성 테이블이 아직 없는지 확인하세요.
package main import ( "context" "fmt" "github.com/amzn/ion-go/ion" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/qldbsession" "github.com/awslabs/amazon-qldb-driver-go/v2/qldbdriver" ) func main() { awsSession := session.Must(session.NewSession(aws.NewConfig().WithRegion("
us-east-1
"))) qldbSession := qldbsession.New(awsSession) driver, err := qldbdriver.New( "quick-start", qldbSession, func(options *qldbdriver.DriverOptions) { options.LoggerVerbosity = qldbdriver.LogInfo }) if err != nil { panic(err) } defer driver.Shutdown(context.Background()) _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { _, err := txn.Execute("CREATE TABLE People") if err != nil { return nil, err } // When working with QLDB, it's recommended to create an index on fields we're filtering on. // This reduces the chance of OCC conflict exceptions with large datasets. _, err = txn.Execute("CREATE INDEX ON People (firstName)") if err != nil { return nil, err } _, err = txn.Execute("CREATE INDEX ON People (age)") if err != nil { return nil, err } return nil, nil }) if err != nil { panic(err) } _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("INSERT INTO People {'firstName': 'Jane', 'lastName': 'Doe', 'age': 77}") }) if err != nil { panic(err) } type Person struct { FirstName string `ion:"firstName"` LastName string `ion:"lastName"` Age int `ion:"age"` } person := Person{"John", "Doe", 54} _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("INSERT INTO People ?", person) }) if err != nil { panic(err) } p, err := driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { result, err := txn.Execute("SELECT firstName, lastName, age FROM People WHERE age = 54") if err != nil { return nil, err } // Assume the result is not empty hasNext := result.Next(txn) if !hasNext && result.Err() != nil { return nil, result.Err() } ionBinary := result.GetCurrentData() temp := new(Person) err = ion.Unmarshal(ionBinary, temp) if err != nil { return nil, err } return *temp, nil }) if err != nil { panic(err) } var returnedPerson Person returnedPerson = p.(Person) if returnedPerson != person { fmt.Print("Queried result does not match inserted struct") } person.Age += 10 _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("UPDATE People SET age = ? WHERE firstName = ?", person.Age, person.FirstName) }) if err != nil { panic(err) } p, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { result, err := txn.Execute("SELECT firstName, lastName, age FROM People WHERE firstName = ?", person.FirstName) if err != nil { return nil, err } var people []Person for result.Next(txn) { ionBinary := result.GetCurrentData() temp := new(Person) err = ion.Unmarshal(ionBinary, temp) if err != nil { return nil, err } people = append(people, *temp) } if result.Err() != nil { return nil, result.Err() } return people, nil }) if err != nil { panic(err) } var people []Person people = p.([]Person) updatedPerson := Person{"John", "Doe", 64} if people[0] != updatedPerson { fmt.Print("Queried result does not match updated struct") } _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("DROP TABLE People") }) if err != nil { panic(err) } }