๐คทโโ๏ธ ๐คทโโ๏ธ Golang์์ jackc/pgx ๋๋ผ์ด๋ฒ ์ฌ์ฉ ์ PostgreSQL ์ค๋ฅ: X๋ฅผ Y๋ก ๋ณํํ ์ ์์
์๊ฐ
์ด๋ด, DEV ์ฌ๋๋ค! ๐ ์ค๋ ์ ๋ "๋จ์ ์ค๋ฅ"๋ผ๋ ์๋ก์ด ์งง์ ๊ธฐ์ฌ ์๋ฆฌ์ฆ๋ฅผ ์์ํฉ๋๋ค. ์ฌ๊ธฐ์์ ์ง๊ธ๊น์ง ํ๋ก๊ทธ๋๋ฐ ์ค์ต์์ ๋ง๋ ๋ค์ํ ๋ง๋ค๋ฅธ ๊ณจ๋ชฉ๊ณผ ํจ์ ์ ๋ค๋ฃฐ ๊ฒ์ ๋๋ค.
์ ๋ ์ด๋ฌํ ๊ธฐ์ฌ๋ฅผ ์์ฑํ ๋ ํญ์ ๋ค์ ๋ค ๊ฐ์ง ๊ท์น์ ๋ฐ๋ฅด๋ ค๊ณ ๋ ธ๋ ฅํ ๊ฒ์ ๋๋ค.
๋๋ฌด ๊ฐํนํ๊ฒ ํ๋จํ์ง ๋ง๊ณ , ๊ทธ๋ฐ ๊ธฐ์ฌ์ ๋ํด ์ด๋ป๊ฒ ์๊ฐํ๋์ง ์ฐ๊ณ , ๋๊ธ์์ ๊ตฌ๋ฌธ ๋ถ์์ ์ํ ์์ ๋ง์ ์ฃผ์ ๋ฅผ ์ ์ํ์ธ์... ์์ํฉ๋๋ค! ๐
๐ ๋ชฉ์ฐจ
์ค๋ฅ ์ค๋ช
๊ณ ์ฑ๋ฅ ๋๋ผ์ด๋ฒjackc/pgx๋ฅผ ํตํด PostgreSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ์ฌ Golang์์ REST API(๋๋ ๊ธฐํ ์ ํ)๋ฅผ ๊ฐ๋ฐํ ๋ ๋๋๋ก ์ ๋ณด ๊ฒ์์ ํผ๋์ ์ค ์ ์๋ ๊ฐ๋จํ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ํนํ, ์ ๊ท ์ด๋ฏผ์.
์ด ๊ฐ๋จํ ์ค๋ฅ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
cannot convert [SOMETHING] to [SOMETHING]
. ์ ๊ฒฝ์ฐ์๋ cannot convert 1 to Text
์ฒ๋ผ ๋ณด์์ต๋๋ค.์ด ์ค๋ฅ ๋ฉ์์ง๋ jackc/pgx ํจํค์ง์์ ๋ฐ์ํ๋ฉฐ ๋ด๋ถ์ ์ผ๋ก ์ค๋น๋ ๋ช ๋ น๋ฌธ์ ์ฌ์ฉํ๋ ์ด ํจํค์ง์ ์๋ฆฌ ํ์์์ ์ ํ์ ๊ฒฐ์ ํ ์ ์๋ PostgreSQL์ ์กฐํฉ์ผ๋ก ์ธํด ๋ฐ์ํฉ๋๋ค.
๐ Thanks for this explanation to author of this comment.
โ Table of contents
์ค๋ฅ ๋ฐ์ ์ ์ ๋ ฅ ๋ฐ์ดํฐ
๋จผ์ ๋ด ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ๋ก์ ํธ ํ ์ด๋ธ์ ์์ฑํ๋ ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
-- ./platform/migration/000001_create_init_tables.up.sql
-- Create projects table
CREATE TABLE "projects" (
"id" UUID PRIMARY KEY DEFAULT (uuid_generate_v4()),
"created_at" timestamp DEFAULT (now()),
"updated_at" timestamp,
"user_id" UUID NOT NULL,
"alias" varchar(255) UNIQUE NOT NULL,
"project_status" int NOT NULL,
"project_attrs" JSONB NOT NULL
);
// ...
ํ๋์๋ ๋งค์ฐ ๊ตฌ์ฒด์ ์ธ ์ ํ์ด ์์ผ๋ฉฐ ์ด ํ ์ด๋ธ์์ ๋ฐ์ดํฐ๋ฅผ ์์ฑ/์์ ํ ๋ Postgres์์ ์ ํจ์ฑ์ ๊ฒ์ฌํฉ๋๋ค.
์ด์ ์ด ๋ง์ด๊ทธ๋ ์ด์ ์ ์ ํฉํ Go ๋ชจ๋ธ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
// ./app/controllers/project_model.go
// Project struct to describe project object.
type Project struct {
ID uuid.UUID `db:"id" json:"id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
UserID uuid.UUID `db:"user_id" json:"user_id"`
Alias string `db:"alias" json:"alias"`
ProjectStatus int `db:"project_status" json:"project_status"`
ProjectAttrs ProjectAttrs `db:"project_attrs" json:"project_attrs"`
}
// ProjectAttrs struct to describe project attributes.
type ProjectAttrs struct {
Title string `json:"title"`
Description string `json:"description"`
Picture string `json:"picture"`
URL string `json:"url"`
}
// ...
์, Go ๋ชจ๋ธ์
JSOB
ํ๋ ์ ํ์ด ์ ๊ท ๊ตฌ์กฐ๊ฐ ๋์ด project_attrs
๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋์ JSON ํ์์ผ๋ก ์ ์ฅ๋๋ค๋ ๊ฒ์ด ๋ง์ต๋๋ค.๐ Other fields are quite normal for any Go project.
โ Table of contents
์ค๋ฅ ํด๊ฒฐ
์ด ๊ฐ๋จํ ์ค๋ฅ์ ๋ํ ํด๊ฒฐ์ฑ ์ผ๋ก ์ํํ๊ฒ ์ด๋ํฉ์๋ค.
์๋ฃจ์ ์ ๋ํด ์์์ผ ํ ๊ฒ์ PostgreSQL์์ ์ฟผ๋ฆฌ์์ ์ง์ ์๋ฆฌ ํ์์์ ๋ํ ์ ํ์ ์ง์ ํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ์์ ์ง์ ํ ์ ํ์ ์ฟผ๋ฆฌ์ ์ถ๊ฐํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
ํ๋ ์ ํ์ ์ง์ ํ๋ ํ์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
$N::<TYPE>
(๋ฌ๋ฌ ๊ธฐํธ + ์๋ฆฌ ํ์์ ๋ฒํธ + ๋ ๊ฐ์ ์ฝ๋ก + DB์ ํ๋ ์ ํ).// ./app/controllers/project_query.go
// CreateProject method for creating project by given Project object.
func (q *ProjectQueries) CreateProject(p *models.Project) error {
// Define query string.
// We define type for each field to solve this simple error.
query := `
INSERT INTO projects
VALUES ($1::uuid, $2::timestamp, $3::timestamp, $4::uuid, $5::varchar, $6::int, $7::jsonb)
`
// Send query to database.
_, err := q.Exec(query, p.ID, p.CreatedAt, p.UpdatedAt, p.UserID, p.Alias, p.ProjectStatus, p.ProjectAttrs)
if err != nil {
// Return only error.
return err
}
// This query returns nothing.
return nil
}
// ...
โ๏ธ Once again, please note that we are specifying the PostgreSQL field type from the migration, not the Go structure from the model!
ํ๋ก์ ํธ๋ฅผ ๋น๋ํ๊ณ ์ด ๋์ ์ ์์ฒญํ๋ฉด ์ค๋ฅ๊ฐ ๋ ์ด์ ํ์๋์ง ์๊ณ ์์ฒญ์ด ์ฑ๊ณตํฉ๋๋ค! ๐
โ Table of contents
๊ฒฐ๋ก
๊ฐ์ธ์ ์ผ๋ก ์ ๋ jackc/pgx ํจํค์ง ๊ตฌ์ฑ์์ ์ด ๊ฒ์ฌ๋ฅผ ์์ ํ ๋นํ์ฑํํ๋ ๊ฒ๋ณด๋ค ์ด๋ฐ ์ข ๋ฅ์ ํญ๋ชฉ์ ๋ ์ข์ํฉ๋๋ค(์ถ๊ฐ ์ ๋ณดhere ).
์ปจํธ๋กค๋ฌ์์ ๊ตฌํ์ ์ธ๋ถ ์ฌํญ์ ๋ฐ์ด๋ค ํ์ ์์ด SQL ์ฟผ๋ฆฌ๋ฅผ ํ๋์ ๋ณผ ์ ์๊ธฐ ๋๋ฌธ์ ํ๋ ์ ํ์ ์ฆ์ ์ดํดํ ์ ์์ต๋๋ค.
์์ ์๊ฒ ํธ๋ฆฌํ ์ต์ ์ ์ ํํ๊ณ ์ฌ์ฉํ์ญ์์ค. ๋ฐฉ๊ธ ๊ฐ์ธ์ ์ผ๋ก ๋์์ด ๋ ์๋ฃจ์ ์ ๋ฐฉ๋ฒ์ ๋ณด์ฌ ๋๋ ธ์ต๋๋ค. ์ฑ๊ณต์ ์ธ ์์ ์ ์ํํ๊ณ ๊ฐ๋จํ ์ค๋ฅ๋ก ์ธํด ํ๋ก์ ํธ๋ฅผ ์คํํ๋ ๋ฐ ๋ฐฉํด๊ฐ ๋์ง ์๋๋ก ํ์ญ์์ค! ๐
โ Table of contents
์ฌ์ง ๋ฐ ๋์์
์ถ์
์ด ๋ธ๋ก๊ทธ์์ ์ด์ ๊ฐ์ ๊ธฐ์ฌ๋ฅผ ๋ ์ํ์๋ฉด ์๋์ ๋๊ธ์ ๊ฒ์ํ๊ณ ์ ๋ฅผ ๊ตฌ๋ ํ์ญ์์ค. ๊ฐ์ฌ! ๐
๊ทธ๋ฆฌ๊ณ ๋ฌผ๋ก LiberaPay ์ ๊ธฐ๋ถํ์๋ฉด ์ ๋ฅผ ํ์ํ์ค ์ ์์ต๋๋ค. ๊ฐ ๊ธฐ๋ถ๊ธ์ ์๋ก์ด ๊ธฐ์ฌ๋ฅผ ์์ฑํ๊ณ ์ปค๋ฎค๋ํฐ๋ฅผ ์ํ ๋น์๋ฆฌ ์คํ ์์ค ํ๋ก์ ํธ๋ฅผ ๊ฐ๋ฐํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐คทโโ๏ธ ๐คทโโ๏ธ Golang์์ jackc/pgx ๋๋ผ์ด๋ฒ ์ฌ์ฉ ์ PostgreSQL ์ค๋ฅ: X๋ฅผ Y๋ก ๋ณํํ ์ ์์), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://dev.to/koddr/postgresql-error-with-using-over-jackc-pgx-driver-in-golang-cannot-convert-x-to-y-1e6eํ ์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค