Хранить рекурсивные структуры go в базе данных Postgresql

У меня есть две структуры (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)
}

person Battalgazi    schedule 19.01.2018    source источник


Ответы (1)


ПРИМЕЧАНИЕ. Это не настоящий ответ, а просто более длинный комментарий к SQL-части вопроса. К сожалению, у меня нет опыта работы с sqlx, поэтому я не могу вам в этом помочь.


То, что у вас есть, похоже, является отношением «многие ко многим». Лицо может принадлежать нескольким Арендаторам, а Арендатор может иметь несколько Лиц.

В SQL это обычно обрабатывается тем, что иногда называют связующей или соединительной таблицей.

-- 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 mkopriva    schedule 19.01.2018