首页 > 解决方案 > 如何在 postgres 数据库中编写嵌套切片?

问题描述

这可能看起来像一个愚蠢的问题,但我正在努力让这个工作。这里有一些细节,我想和你分享,这样你可能会更好地理解我的意思。首先,我只是想学习编码,并尝试为自己实现在一个小项目中学到的东西。请多多包涵 :)

当前设置

我正在获取一个外部 API 端点,其中 json 如下所示:

{
    "orders": [
        {
            "input": {
                "amount": "1",
                "currency": "EUR",
                "type": "bank_account",
                "iban": "DEXXX"
            },
            "output": {
                "amount": "2",
                "currency": "CHF",
                "type": "paypal",
                "paypal_recipient": "example@example.org"
            },
            "id": "8e150ca6",
            "timestamp_created": "2021-06-06T20:34:19.827Z",
            "timestamp_executed": "2021-06-07T06:43:57Z",
            "timestamp_awaiting_payment_since": "2021-06-06T20:34:28.921Z",
            "timestamp_payment_received": "2021-06-07T06:43:57Z",
            "payment_details": {
                "iban": "DEXXX",
                "recipient_name": "Company1",
                "recipient_postal_address": [
                    "Maxstreet",
                    "1000 Berlin                                                                  ",
                    "Germany"
                ],
                "reference": "Order XY",
                "swift_bic": "BCNNXX",
                "type": "bank_account"
            },
            "price_breakdown": {
                "customer_trading_fee": {
                    "amount": "1.56",
                    "currency": "EUR"
                },
                "non-verified_fee": {
                    "amount": "0.79",
                    "currency": "EUR"
                },
                "partner_fee": {
                    "amount": "3.4",
                    "currency": "EUR"
                }
            }
        },
        {
            "input": {.....
        },
    "pagination": {
        "current": 1,
        "first": 1,
        "last": 1
    }
}

我有几个 Structs,它们确实重印了 json 的构建方式:

    Type OrderStructDB struct {
    gorm.Model
    OrderID                       string    `gorm:"unique;not null"`
    TimestampCreated              time.Time `json:"timestamp_created"`
    TimestampCancelled            time.Time `json:"timestamp_cancelled"`
    TimestampAwaitingPaymentSince time.Time `json:"timestamp_awaiting_payment_since"`
    InputStructID                 uint      `gorm:"foreignKey:InputStruct"`
    InputStruct                   InputStruct
    OutputStructID                uint `gorm:"foreignKey:OutputStruct"`
    OutputStruct                  OutputStruct
    PriceBreakdownStructID        uint `gorm:"foreignKey:PriceBreakdownStruct"`
    PriceBreakdownStruct          PriceBreakdownStruct
    //PaymentDetailsStructID        uint `gorm:"foreignKey:PaymentDetailsStruct"`
    //PaymentDetailsStruct          PaymentDetailsStruct

}

type OrderStruct struct {
    Input                         InputStruct          `json:"input" ,gorm:"foreignKey:ID"`
    Output                        OutputStruct         `json:"output" ,gorm:"foreignKey:ID"`
    OrderID                       string               `json:"id" ,gorm:"unique;not null"`
    TimestampCreated              time.Time            `json:"timestamp_created"`
    TimestampCancelled            time.Time            `json:"timestamp_cancelled"`
    TimestampAwaitingPaymentSince time.Time            `json:"timestamp_awaiting_payment_since"`
    PaymentDetails                PaymentDetailsStruct `json:"payment_details" ,gorm:"embedded;embeddedPrefix:paymentdetails_,foreignKey:ID"`
    PriceBreakdown                PriceBreakdownStruct `json:"price_breakdown" ,gorm:"embedded;embeddedPrefix:pricebreakdown_,foreignKey:ID"`
    MessageToSign                 MessageToSignStruct  `json:"message_to_sign,omitempty"`

    //PaymentDetailsStructID        uint `gorm:"foreignKey:PaymentDetailsStruct"`
    //PaymentDetailsStruct          PaymentDetailsStruct

}

type InputStruct struct {
    Amount   string `json:"amount"`
    Currency string `json:"currency"`
    Type     string `json:"type"`
    Iban     string `json:"iban"`
    gorm.Model
}
type OutputStruct struct {
    Amount        string `json:"amount"`
    Currency      string `json:"currency"`
    Type          string `json:"type"`
    CryptoAddress string `json:"crypto_address"`
    gorm.Model
}
type PaymentDetailsStruct struct {
    Iban                   string   `json:"iban"`
    RecipientName          string   `json:"recipient_name"`
    RecipientPostalAddress []string `json:"recipient_postal_address"`
    Reference              string   `json:"reference"`
    SwiftBic               string   `json:"swift_bic"`
    Type                   string   `json:"type"`
}
type CustomerTradingFeeStruct struct {
    Amount   string `json:"amount"`
    Currency string `json:"currency"`
    gorm.Model
}
type PriceBreakdownStruct struct {
    CustomerTradingFeeID uint                     `gorm:"foreignKey:CustomerTradingFee"`
    CustomerTradingFee   CustomerTradingFeeStruct `json:"customer_trading_fee" ,gorm:"references:PriceBreakdownID"`
    NonVerifiedFeeID     uint                     `gorm:"foreignKey:NonVerifiedFee"`
    NonVerifiedFee       NonVerifiedFeeStruct     `json:"non-verified_fee" ,gorm:"references:PriceBreakdownID"`
    PartnerFeeID         uint                     `gorm:"foreignKey:ParnterFee"`
    PartnerFee           PartnerFeeStruct         `json:"partner_fee" ,gorm:"references:PriceBreakdownID"`
    gorm.Model
}

type MessageToSignStruct struct {
    Body                   string `json:"body"`
    SignatureSubmissionURL string `json:"signature_submission_url"`
}

type NonVerifiedFeeStruct struct {
    Amount   string `json:"amount"`
    Currency string `json:"currency"`
    gorm.Model
}

type PartnerFeeStruct struct {
    Amount   string `json:"amount"`
    Currency string `json:"currency"`
    gorm.Model
}

type OrdersStruct struct {
    Orders     []OrderStruct    `json:"orders"`
    Pagination PaginationStruct `json:"pagination"`
}

type PaginationStruct struct {
    Current int `json:"current"`
    First   int `json:"first"`
    Last    int `json:"last"`
}

到目前为止,我管理的是:

我在哪里挣扎

我真的不确定,如何使用“OrdersStruct”,嵌套的“OrderStruct”切片,并将相同的详细信息写入数据库,如“OrderStructDB”中所述。我尝试了一些变体,但下班后我无法让它工作。

这是获取单个订单并将其写入数据库的代码部分的样子:

func getOrder() (Order OrderStruct) {

    conf := getToken()
    client := conf.Client(context.Background())

    res, err := client.Get("https://api.endpoint/v1/orders/baa1f5f4")
    if err != nil {
        log.Fatal(err.Error())
    }
    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        log.Fatal(err.Error())
    }

    var formattedBody OrderStruct
    err = json.Unmarshal(body, &formattedBody)
    if err != nil {
        log.Fatal(err.Error())
    }

    // Create DB Entry Logic and Struct
    // Connect DB
    db := helpers.ConnectDB()
    order := OrderStructDB{
        OrderID:                       formattedBody.OrderID,
        InputStruct:                   formattedBody.Input,
        OutputStruct:                  formattedBody.Output,
        PriceBreakdownStruct:          formattedBody.PriceBreakdown,
        TimestampCreated:              formattedBody.TimestampCreated,
        TimestampCancelled:            formattedBody.TimestampCancelled,
        TimestampAwaitingPaymentSince: formattedBody.TimestampAwaitingPaymentSince,
    }

    err = db.Create(&order).Error
    if err, ok := err.(*pq.Error); ok && err.Code.Name() == "unique_violation" {
        helpers.HandleErr(err)
        // handle error
    }

    defer db.Close()

    return formattedBody
}

这是片段,我在其中获取所有订单,但没有设法将其输入数据库。我已经删除了所有尝试,试图将其放入数据库中:

func getOrders() (Orders OrdersStruct) {

    conf := getToken()
    client := conf.Client(context.Background())

    res, err := client.Get("https://api.endpoint/v1/orders")
    if err != nil {
        log.Fatal(err.Error())
    }

    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        log.Fatal(err.Error())
    }

    var formattedBody OrdersStruct
    err = json.Unmarshal(body, &formattedBody)
    helpers.HandleErr(err)

    // Connect DB
    db := helpers.ConnectDB()

    //Define the StructMapping, my problem lies probably here. How to map the details of slice struct into a struct, i can map into the databse


    err = db.Create(&orders).Error
    if err, ok := err.(*pq.Error); ok && err.Code.Name() == "unique_violation" {
        helpers.HandleErr(err)
        // handle error
    }

    defer db.Close()

    return formattedBody
}

我在该部分添加了一个小评论,我相信我有错误。我想将 OrdersStruct 的元素放入 OrderStructDB,因为我希望存储的信息与单个订单相同。但我无法让它几乎正常工作。我尝试了几种方法,例如:

    orders := OrderStructDB{
        OrderID:                       formattedBody.Orders.OrderID,
        InputStruct:                   formattedBody.Orders.Input,
        OutputStruct:                  formattedBody.Orders.Output,
        PriceBreakdownStruct:          formattedBody.Orders.PriceBreakdown,
        TimestampCreated:              formattedBody.Orders.TimestampCreated,
        TimestampCancelled:            formattedBody.Orders.TimestampCancelled,
        TimestampAwaitingPaymentSince: formattedBody.Orders.TimestampAwaitingPaymentSince,
    }

但我一直在这里失败。我不确定,实现这一目标的最佳方法是什么。我是否可能还需要创建一个新的 OrdersStructDB 类型。我想到了批量插入,但我是否可能需要遍历切片并创建我的新切片,而不需要 json 的“顶级元素”?

我很感激能得到一些见解和提示,关于我的大脑在哪里停止工作,我在哪里思考错误的方向。

如果对您有帮助,也很高兴分享更多代码。

谢天谢地,

一个试图学习编码的人

标签: restgostructnestedgo-gorm

解决方案


推荐阅读