首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Go SQLBoiler:查询关系并返回

Go SQLBoiler:查询关系并返回
EN

Stack Overflow用户
提问于 2020-01-12 23:14:42
回答 1查看 594关注 0票数 1

我正在使用SQLBoiler,如何查询关系和返回?我有两个独立的数据库表,分别表示产品和它的价格/金额。我想同时查询它们并将它们放在一个列表中一起返回,就像getAll请求一样。

这是初始架构文件。

代码语言:javascript
复制
-- 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);
代码语言:javascript
复制
...

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
}

...

这来自create product,但在产品列表中的预期GraphQL结果几乎相同:

代码语言:javascript
复制
{
  "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文件。

代码语言:javascript
复制
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;
}
EN

回答 1

Stack Overflow用户

发布于 2021-01-27 13:06:02

您想要加载主对象Product及其所有相关的Money行吗?

这应该可以做到:

代码语言:javascript
复制
products, err :=
    models.Products(
        qm.Load(models.ProductRels.ProductMoneys)
    ).All(context.Background(), db)

这将生成并执行两个SQL查询。第一个查询应该是

代码语言:javascript
复制
SELECT * FROM "products"

并将检索所有产品。第二个查询应该类似于

代码语言:javascript
复制
SELECT * FROM "money" WHERE ("money"."product_id" IN ($1,$2,$3))

并将检索所有产品的所有资金。( IN子句的确切内容将取决于返回的产品数量。)

然后,您应该能够访问相关的行,如下所示:

代码语言:javascript
复制
products[0].R.ProductMoneys

注意:ProductRels和/或ProductMoneys可能与SQLBoiler生成的名称不完全相同。我不得不在这里猜测。确保检查生成的代码以获得正确的名称。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59705186

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档