Go SQLBoiler: отношение запроса и возврат - PullRequest
0 голосов
/ 12 января 2020

Я использую SQLBoiler и как запросить отношение и вернуть? У меня есть две отдельные таблицы БД для продукта и его цена / деньги. Я хочу запросить оба и вернуть их вместе в виде списка, например getAll request.

Это исходный файл схемы.

-- schema.sql

drop table if exists products cascade;
drop table if exists money;

create table products (
    id serial not null primary key,
    user_id int not null,
    name varchar(255) not null,
    description text not null,
    created_at timestamptz not null default now(),
    updated_at timestamptz not null default now(),
    deleted_at timestamptz
);

create table money (
    product_id int not null primary key,
    currency_code text not null default 'USD',
    units int not null,
    nanos int not null,
    created_at timestamptz not null default now(),
    updated_at timestamptz not null default now(),

    foreign key (product_id) references products (id) on delete cascade
);

create unique index idx_products_name
on products (name);

insert into products (user_id, name, description) values (1, 'Something', 'This is something.');
insert into products (user_id, name, description) values (2, 'Anything', 'This is anything.');

insert into money (product_id, currency_code, units, nanos) values (1, 'GBP', 450, 75);
insert into money (product_id, currency_code, units, nanos) values (2, 'CAD', 9, 20);
...

func (s *Server) Index(context.Context, *pb.Empty) (*pb.IndexProductResponse, error) {
    db := InitPg()
    defer db.Close()

    // Make a slice of Product type from generated protobuf
    products := make([]*pb.Product, 0)

    // Get all products (without price)
    ps, err := models.Products().All(context.Background(), db)
    LogAndReport(&pb.IndexProductResponse{}, err)

    // How do I query each product's price from money table?
    // Or
    // How do I query all money and assign to each related products?

    // fmt.Println("@ ps here >", ps)

    // Append queried products into products slice to return
    for _, p := range ps {
        products = append(products,
            &pb.Product{
                Id:          int32(p.ID),
                Name:        p.Name,
                Description: p.Description,
                // I need to return/assign price information here.
                // I can do like this with Gorm.
                //
                // Price: &pb.Money{
                //  CurrencyCode: p.Price.CurrencyCode,
                //  Units: p.Price.Units,
                //  Nanos: p.Price.Nanos,
                // },
                UserId:      int32(p.UserID),
            })
    }

    return &pb.IndexProductResponse{Products: products}, nil
}

...

Это от создания продукта, но почти такой же ожидаемый результат GraphQL в списке продуктов:

{
  "data": {
    "products": [
      {
        "id": "1",
        "name": "Something",
        "description": "This is something.",
        "price": {
          "currencyCode": "USD",
          "units": 9,
          "nanos": 93
        },
        "userId": "1"
      },
      {
        "id": "2",
        "name": "Anything",
        "description": "This is anything.",
        "price": {
          "currencyCode": "USD",
          "units": 24,
          "nanos": 56
        },
        "userId": "1"
      }
    ]
  },
...
}
...

Это файл protobuf для обслуживания продуктов.

service ProductService {
  rpc Index(Empty) returns (IndexProductResponse) {}
}

message Money {
  // The 3-letter currency code defined in ISO 4217.
  string currency_code = 1;

  // The whole units of the amount.
  // For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar.
  int64 units = 2;

  // Number of nano (10^-9) units of the amount.
  // The value must be between -999,999,999 and +999,999,999 inclusive.
  // If `units` is positive, `nanos` must be positive or zero.
  // If `units` is zero, `nanos` can be positive, zero, or negative.
  // If `units` is negative, `nanos` must be negative or zero.
  // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.
  int32 nanos = 3;
}

message Product {
  int32 id = 1;
  string name = 2;
  string description = 3;
  Money price = 4;
  int32 user_id = 5;
}

message IndexProductResponse {
  repeated Product products = 1;
}
...