在 Postgresql 数据库中存储递归结构
Store recursive go structs in Postgresql database
我有两个递归引用彼此的结构(Person 和 Tenant)。
我没有使用 'SQL' 的经验,我正在尝试使用 https://github.com/jmoiron/sqlx 库来存储这些结构,使它们保持相互引用,以便我可以再次将它们作为结构检索.
我不知道应该使用哪种类型创建表,或者我应该如何插入对象以使其正常工作。
此外,如果有任何其他 go 库可以轻松处理这种情况,我愿意接受任何建议。
提前致谢。
type Tenant struct {
Id int `db:"id"`
Name string `db:"name"`
Person []Person `db:"person"`
}
type Person struct {
Id int `db:"id"`
Username string `db:"username"`
Tenants *[]Tenant `db:"tenants"`
}
func main() {
var schema = `
CREATE TABLE IF NOT EXISTS person (
id int,
username text
tenants []text //-> type????
);
CREATE TABLE IF NOT EXISTS tenant (
id int,
name text,
person []text //-> type????
)`
psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+
"password=%s dbname=%s sslmode=%s",
host, port, user, password, dbname, sslmode)
db, err := sqlx.Open("postgres", psqlInfo)
if err != nil {
fmt.Println(err)
return
}
defer db.Close()
err = db.Ping()
if err != nil {
panic(err)
}
fmt.Println("Successfully connected!")
db.MustExec(schema)
var tenant1 Tenant
var person1 Person
tenant1 = Tenant{1, "newtenant", []Person{person1}}
person1 = Person{1, "newuser", &[]Tenant{tenant1}}
tx := db.MustBegin()
tx.NamedExec("INSERT INTO tenant (id,name,person) VALUES (:id,:name, :person)", &tenant1)
tx.Commit()
out := []Tenant{}
db.Select(&out, "SELECT * FROM tenant ORDER BY name ASC")
fmt.Println(out)
}
注意: 这不是真正的答案,只是对问题 SQL 部分的较长评论。不幸的是,我没有使用 sqlx 的经验,所以我无法帮助您。
你那里好像是多对多的关系。一个人可以属于多个租户,一个租户可以有多个人。
在 SQL 中,这通常由有时称为链接或联结的东西处理 table。
-- postgresql flavor of SQL
CREATE TABLE IF NOT EXISTS person (
id serial PRIMARY KEY,
username text NOT NULL
);
CREATE TABLE IF NOT EXISTS tenant (
id serial PRIMARY KEY,
name text NOT NULL
);
-- the linking table
CREATE TABLE IF NOT EXISTS person_tenant (
person_id integer NOT NULL REFERENCES person (id),
tenant_id integer NOT NULL REFERENCES tenant (id),
PRIMARY KEY(person_id, tenant_id)
);
我有两个递归引用彼此的结构(Person 和 Tenant)。
我没有使用 'SQL' 的经验,我正在尝试使用 https://github.com/jmoiron/sqlx 库来存储这些结构,使它们保持相互引用,以便我可以再次将它们作为结构检索.
我不知道应该使用哪种类型创建表,或者我应该如何插入对象以使其正常工作。
此外,如果有任何其他 go 库可以轻松处理这种情况,我愿意接受任何建议。
提前致谢。
type Tenant struct {
Id int `db:"id"`
Name string `db:"name"`
Person []Person `db:"person"`
}
type Person struct {
Id int `db:"id"`
Username string `db:"username"`
Tenants *[]Tenant `db:"tenants"`
}
func main() {
var schema = `
CREATE TABLE IF NOT EXISTS person (
id int,
username text
tenants []text //-> type????
);
CREATE TABLE IF NOT EXISTS tenant (
id int,
name text,
person []text //-> type????
)`
psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+
"password=%s dbname=%s sslmode=%s",
host, port, user, password, dbname, sslmode)
db, err := sqlx.Open("postgres", psqlInfo)
if err != nil {
fmt.Println(err)
return
}
defer db.Close()
err = db.Ping()
if err != nil {
panic(err)
}
fmt.Println("Successfully connected!")
db.MustExec(schema)
var tenant1 Tenant
var person1 Person
tenant1 = Tenant{1, "newtenant", []Person{person1}}
person1 = Person{1, "newuser", &[]Tenant{tenant1}}
tx := db.MustBegin()
tx.NamedExec("INSERT INTO tenant (id,name,person) VALUES (:id,:name, :person)", &tenant1)
tx.Commit()
out := []Tenant{}
db.Select(&out, "SELECT * FROM tenant ORDER BY name ASC")
fmt.Println(out)
}
注意: 这不是真正的答案,只是对问题 SQL 部分的较长评论。不幸的是,我没有使用 sqlx 的经验,所以我无法帮助您。
你那里好像是多对多的关系。一个人可以属于多个租户,一个租户可以有多个人。
在 SQL 中,这通常由有时称为链接或联结的东西处理 table。
-- postgresql flavor of SQL
CREATE TABLE IF NOT EXISTS person (
id serial PRIMARY KEY,
username text NOT NULL
);
CREATE TABLE IF NOT EXISTS tenant (
id serial PRIMARY KEY,
name text NOT NULL
);
-- the linking table
CREATE TABLE IF NOT EXISTS person_tenant (
person_id integer NOT NULL REFERENCES person (id),
tenant_id integer NOT NULL REFERENCES tenant (id),
PRIMARY KEY(person_id, tenant_id)
);