Gorm: Как сохранить структуру в поле

Я пытаюсь сохранить идентификатор контракта hederea типа * hedera.ContractID в поле Gorm, но получаю сообщение об ошибке «недопустимое поле найдено для поля struct github.com/hashgraph/hedera-sdk-go/v2.AccountID AliasKey: определите действительный внешний ключ для отношений или реализовать интерфейс Valuer"

пакетный контракт

import (
    "fmt"

    "github.com/.../scanner/controllers/blockchain"
    database "github.com/.../scanner/db"
    model "github.com/.../scanner/models"
    "github.com/rs/xid"
    "gorm.io/gorm"
)

func DeployContract() *gorm.DB {

    //connect to database
    db, err := database.ConnectToDB()

    //if db connection fails
    if err != nil {
        panic(err)
    }

    //init model
    var modelContract model.Contract

    //check if a contract has been deployed
    if err := db.First(&modelContract); err.Error != nil {
        //no deployment found

        //Migrate the schema
        db.AutoMigrate(&model.Contract{})

        //deploy contract
        contract, _ := blockchain.DeployContract()

        //create record

        // generate random id
        id := xid.New()

        // Create
        db.Create(&model.Contract{
            Id:            id.String(),
            ContractId:    contract.Receipt.ContractID,
            GasUsed:       contract.CallResult.GasUsed,
            TransactionId: fmt.Sprint(contract.TransactionID),
            Timestamp:     contract.ConsensusTimestamp,
            ChargeFee:     fmt.Sprint(contract.TransactionFee),
            PayerAccount:  fmt.Sprint(contract.TransactionID.AccountID),
            Status:        fmt.Sprint(contract.Receipt.Status),
        })

    }

    return db
}

Модель Горма

package models

import (
    "time"

    "github.com/hashgraph/hedera-sdk-go/v2"
    "gorm.io/gorm"
)

type Contract struct {
    gorm.Model
    Id            string
    ContractId    *hedera.ContractID
    GasUsed       uint64
    TransactionId string
    Timestamp     time.Time
    ChargeFee     string
    PayerAccount  string
    Status        string
}
Шаблоны Angular PrimeNg
Шаблоны Angular PrimeNg
Как привнести проверку типов в наши шаблоны Angular, использующие компоненты библиотеки PrimeNg, и настроить их отображение с помощью встроенной...
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Начала с розового дизайна
Начала с розового дизайна
Pink Design - это система дизайна Appwrite с открытым исходным кодом для создания последовательных и многократно используемых пользовательских...
Шлюз в PHP
Шлюз в PHP
API-шлюз (AG) - это сервер, который действует как единая точка входа для набора микросервисов.
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
0
0
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Для пользовательских типов данных вам необходимо указать, как значение будет храниться и извлекаться из вашей базы данных. Это делается путем реализации интерфейсов Scanner и Valuer.

Однако, поскольку hedera.ContractID определен в другом пакете, вам нужно будет создать свой собственный ContractID и реализовать эти интерфейсы. Что-то вроде этого:

type ContractID hedera.ContractID

type Contract struct {
    gorm.Model
    Id            string
    ContractId    *ContractID
    GasUsed       uint64
    TransactionId string
    Timestamp     time.Time
    ChargeFee     string
    PayerAccount  string
    Status        string
}     

func (c *ContractID) Scan(value interface{}) error {
  bytes, ok := value.([]byte)
  if !ok {
    return errors.New(fmt.Sprint("Failed to unmarshal ContractID value:", value))
  }

  return json.Unmarshal(bytes, c)
}

func (c ContractID) Value() (driver.Value, error) {
  return json.Marshal(c)
}

Кроме того, вставьте hedera.ContractID в model.ContractID, где бы оно ни использовалось. Например:

    cID := model.ContractID(*contract.Receipt.ContractID)

    // Create
    db.Create(&model.Contract{
        Id:            id.String(),
        ContractId:    &cID,
        GasUsed:       contract.CallResult.GasUsed,
        TransactionId: fmt.Sprint(contract.TransactionID),
        Timestamp:     contract.ConsensusTimestamp,
        ChargeFee:     fmt.Sprint(contract.TransactionFee),
        PayerAccount:  fmt.Sprint(contract.TransactionID.AccountID),
        Status:        fmt.Sprint(contract.Receipt.Status),
    })

Спасибо за сообщение, но как я могу его применить.

mev 21.11.2022 10:39

Добавьте этот код в свой код (возможно, там, где определена ваша структура Contract).

Emin Laletovic 21.11.2022 11:54

Спасибо за ответ. Все еще не могу заставить его работать. Вот что я сделал play.golang.com/p/id4GlSqi0-a ​​

mev 21.11.2022 13:10

Я обновил свой код пользовательским определением ContractID.

Emin Laletovic 21.11.2022 15:47

Спасибо за сообщение, сканер/оценщик работает, но при попытке создать экземпляр БД с помощью db.Create я получаю сообщение об ошибке IncompileAssign для ContractId (сохранение значения contract.Receipt.ContractID), так как теперь он должен иметь тип ContractID hedera .ContractID

mev 21.11.2022 16:53

В ответ добавлен дополнительный код, потому что вам нужно преобразовать hedera.ContractID в models.ContractID.

Emin Laletovic 21.11.2022 23:42

Можно ли преобразовать ContractId, прочитанный из БД. вернуться к *hedera.ContractID

mev 23.11.2022 10:45

вы должны быть в состоянии сделать что-то вроде hederaContractID := hedera.ContractID(cID), где cID имеет тип model.ContractID.

Emin Laletovic 23.11.2022 11:10

Большое спасибо, все получилось. В итоге я сделал hederaContractID := hedera.ContractID(*cID); еще раз спасибо.

mev 23.11.2022 13:52

Другие вопросы по теме