目次
问题内容
解决方法
ホームページ バックエンド開発 Golang Gorm からクエリに渡された Postgres データ型が正しくありません

Gorm からクエリに渡された Postgres データ型が正しくありません

Feb 15, 2024 pm 12:06 PM
ユーザー登録

从 Gorm 传入查询的 Postgres 数据类型不正确

在使用 Gorm 进行 Postgres 数据库查询时,有时会遇到一个常见的问题:“从 Gorm 传入查询的 Postgres 数据类型不正确”。这个问题可能会导致查询结果不准确,给开发者带来困扰。在本文中,php小编鱼仔将为您解析这个问题的原因,并提供解决方案,帮助您正确处理数据类型,确保查询结果的准确性。

问题内容

我正在尝试在 api 中创建一个端点来创建公司。在公司模型中,我有一个 []string 用于存储与允许用户注册的电子邮件相关的允许列出的域。

[]字符串最初是从数组的 json post 请求映射的,并在 postgres 中分配了 text[] 类型。

alloweddomains        []string `gorm:"type:text[];default:null" json:"alloweddomains" binding:"required"`
ログイン後にコピー

使用 create() 的完整模型

// company is the primary struct type for companies
type company struct {
    common.base
    name                  string   `gorm:"unique;default:not null" json:"name" binding:"required"`
    primarycontactname    string   `gorm:"unique;default:not null" json:"primarycontactname" binding:"required"`
    primarycontactemail   string   `gorm:"unique;default:not null" json:"primarycontactemail" binding:"required"`
    primarycontactphone   string   `gorm:"unique;default:not null" json:"primarycontactphone" binding:"required"`
    secondarycontactname  string   `gorm:"unique;default:null" json:"secondarycontactname"`
    secondarycontactemail string   `gorm:"unique;default:null" json:"secondarycontactemail"`
    secondarycontactphone string   `gorm:"unique;default:null" json:"secondarycontactphone"`
    primarydomain         string   `gorm:"unique;default:not null" json:"primarydomain" binding:"required"`
    alloweddomains        []string `gorm:"type:text[];default:null" json:"alloweddomains" binding:"required"`
    mfaenabled            bool     `gorm:"not null" json:"mfaenabled" binding:"required"`
    isvalidated           bool     `gorm:"not null"`
}

func (c *company) create() error {
    if result := common.db.create(c); result.error != nil {
        log.printf("error creating company: %s", c.name)
        return result.error
    } else {
        log.printf("successfully created company: %s", c.name)
        return nil
    }
}
ログイン後にコピー

在实现这个过程中,我遇到了两个问题。

首先,当 alloweddomains 包含单个字符串时,该值不会作为数组写入 postgres,而是作为单个字符串写入。

api               | 2023/04/10 19:05:50 /go/src/api/company/model.go:25 error: malformed array literal: "website.co.uk" (sqlstate 22p02)
api               | [2.006ms] [rows:0] insert into "companies" ("created_at","updated_at","deleted_at","name","primary_contact_name","primary_contact_email","primary_contact_phone","primary_domain","mfa_enabled","is_validated","secondary_contact_name","secondary_contact_email","secondary_contact_phone","allowed_domains") values ('2023-04-10 19:05:50.551','2023-04-10 19:05:50.551',null,'foo company ltd.','foo','bar','00000000000','website.com',true,false,'foo2','bar2','11111111111',('website.co.uk')) returning "id","uuid","secondary_contact_name","secondary_contact_email","secondary_contact_phone","allowed_domains"
api               | [gin] 2023/04/10 - 19:05:50 | 500 |    3.043083ms |      172.21.0.1 | post     "/api/company/register"
api               | 2023/04/10 19:05:50 error creating company: foo company ltd.
api               | 2023/04/10 19:05:50 error: malformed array literal: "website.co.uk" (sqlstate 22p02)
postgres          | 2023-04-10 19:06:35.523 utc [19] error:  column "allowed_domains" is of type text[] but expression is of type record at character 336
postgres          | 2023-04-10 19:06:35.523 utc [19] hint:  you will need to rewrite or cast the expression.
postgres          | 2023-04-10 19:06:35.523 utc [19] statement:  insert into "companies" ("created_at","updated_at","deleted_at","name","primary_contact_name","primary_contact_email","primary_contact_phone","primary_domain","mfa_enabled","is_validated","secondary_contact_name","secondary_contact_email","secondary_contact_phone","allowed_domains") values ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,($14,$15)) returning "id","uuid","secondary_contact_name","secondary_contact_email","secondary_contact_phone","allowed_domains"
ログイン後にコピー

其次,当 json 数组包含 > 1 值时,写入数据库的类型为 record 类型,而不是 text[]

api               | 2023/04/10 19:06:35 /go/src/api/company/model.go:25 ERROR: column "allowed_domains" is of type text[] but expression is of type record (SQLSTATE 42804)
api               | [2.502ms] [rows:0] INSERT INTO "companies" ("created_at","updated_at","deleted_at","name","primary_contact_name","primary_contact_email","primary_contact_phone","primary_domain","mfa_enabled","is_validated","secondary_contact_name","secondary_contact_email","secondary_contact_phone","allowed_domains") VALUES ('2023-04-10 19:06:35.522','2023-04-10 19:06:35.522',NULL,'Foo Company Ltd.','Foo','Bar','00000000000','website.com',true,false,'Foo2','Bar2','11111111111',('website.co.uk','website.net')) RETURNING "id","uuid","secondary_contact_name","secondary_contact_email","secondary_contact_phone","allowed_domains"
api               | [GIN] 2023/04/10 - 19:06:35 | 500 |    3.256334ms |      172.21.0.1 | POST     "/api/company/register"
api               | 2023/04/10 19:06:35 Error creating company: Foo Company Ltd.
api               | 2023/04/10 19:06:35 ERROR: column "allowed_domains" is of type text[] but expression is of type record (SQLSTATE 42804)
ログイン後にコピー

当我设置断点并在序列化后分析 company 类型时,很明显 alloweddomains 的类型是正确的。

我在这里缺少什么想法或者解决这个问题的最佳方法吗?

解决方法

根据 mkopriva 的评论,解决方案是使用 pq 包,如下所示。

package company

import (
    "github.com/lib/pq"
    "log"
)

// Company is the primary struct type for companies
type Company struct {
    ...
AllowedDomains        pq.StringArray `gorm:"type:text[];default:NULL" json:"allowedDomains" binding:"required"`
}

func (c *Company) Create() error {
    a := pq.StringArray{}
    if c.AllowedDomains != nil && len(c.AllowedDomains) > 0 {
        for _, v := range c.AllowedDomains {
            a = append(a, v)
        }
        c.AllowedDomains = a
    }
    if result := common.Db.Create(c); result.Error != nil {
        log.Printf("Error creating company: %s", c.Name)
        return result.Error
    } else {
        log.Printf("Successfully created company: %s", c.Name)
        return nil
    }
}
ログイン後にコピー

以上がGorm からクエリに渡された Postgres データ型が正しくありませんの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

鉄道12306メールアドレスの登録方法 鉄道12306メールアドレスの登録方法 Apr 30, 2024 am 11:33 AM

Railway 12306 の電子メール アドレスを登録する手順は次のとおりです。 12306 の Web サイトにアクセスし、[登録] をクリックして、電子メール、名前、携帯電話、その他の情報を入力し、パスワードと秘密の質問を設定します。プロンプトに、認証情報用の電子メール認証コードと携帯電話認証コードを入力し、「登録を完了」をクリックします。

Bitget Wallet 取引所に登録できないのはなぜですか? Bitget Wallet 取引所に登録できないのはなぜですか? Sep 06, 2024 pm 03:34 PM

BitgetWallet 取引所に登録できない理由は、アカウント制限、サポートされていない地域、ネットワークの問題、システム メンテナンス、技術的障害などさまざまです。 BitgetWallet 取引所に登録するには、公式 Web サイトにアクセスして情報を入力し、規約に同意して登録を完了し、本人確認を行ってください。

なぜDouyinは2つのアカウントを持っているのですか?携帯電話に2つのTikTokをインストールするにはどうすればよいですか? なぜDouyinは2つのアカウントを持っているのですか?携帯電話に2つのTikTokをインストールするにはどうすればよいですか? May 06, 2024 pm 09:28 PM

デジタル時代において、ソーシャルメディアは人々の生活に不可欠な部分となっています。 Douyin は、中国で最も人気のあるショートビデオ プラットフォームの 1 つとして、多くのユーザーを魅了しています。アカウントを 2 つ登録しているユーザーもいます。では、Douyin はなぜ 2 つのアカウントを持っているのでしょうか?この記事では、この質問に答え、携帯電話に 2 つの Douyin アカウントをインストールする方法を説明します。 1. なぜDouyinは2つのアカウントを持っているのですか?機能の差別化: ユーザーによっては、コンテンツの種類や機能に基づいてアカウントを区別する場合があります。たとえば、あるアカウントは日常生活を共有するために使用され、別のアカウントは専門的なスキルを示すために使用されます。 2. プライバシー保護: 一部のユーザーは、2 つのアカウントを通じてプライバシーを保護し、生活と仕事を分離し、情報漏洩を回避したいと考えています。 3. インタラクションのニーズ: インタラクションのニーズにより、ユーザーによっては 2 つを登録する場合があります。

Douyinのスパークカラー変更ルールの詳しい説明は何ですか?条件に合わせた多彩なスパークカラー Douyinのスパークカラー変更ルールの詳しい説明は何ですか?条件に合わせた多彩なスパークカラー May 04, 2024 am 09:31 AM

ユーザー インタラクションを強化し、ユーザー エクスペリエンスを向上させるために、Douyin プラットフォームは興味深いインタラクティブ メカニズムである Spark を開始しました。ユーザーは、Douyin での一連のアクションを通じてスパークをアクティブ化し、アップグレードすることができます。異なる色は、異なる成果と名誉を表します。 Douyin Spark の色変更ルールを理解すると、ユーザーがより適切に参加して対話し、Douyin によってもたらされるソーシャルな楽しみを楽しむことができます。 1.Douyinのスパークカラー変更ルールの詳しい説明は何ですか? 1. 行動は、いいね、コメント、共有などのユーザーのインタラクティブな行動を活性化し、火花を散らす可能性があります。 2. レベルの向上 ユーザーのインタラクションが増えると、スパークは徐々にアップグレードされ、それに応じて色が変化します。 3. 色の変化 スパークの色の変化は、通常、ユーザーのインタラクション頻度、インタラクションの質、アクティビティへの参加に対する熱意に関連しています。 4. タスクが完了しました

Deepseekの公式ウェブサイトの入り口と最新のプロモーションアクティビティ Deepseekの公式ウェブサイトの入り口と最新のプロモーションアクティビティ Feb 19, 2025 pm 05:15 PM

Deepseekの公式Webサイトは現在、ユーザーにショッピングエクスペリエンスを提供するための複数の割引アクティビティを開始しています。新規ユーザーはサインアップして10ドルのクーポンを取得し、視聴者全員に15%の限定時間割引を享受します。友人は報酬を獲得することもできます。また、買い物時に贈り物を償還するためにポイントを蓄積することができます。イベントの締め切りは違う。

トマトの小説でタスクを完了する方法 トマトの小説でタスクを完了する方法 May 03, 2024 am 02:27 AM

トマトノベルズのタスクを完了すると、コインとポイントを獲得できます。 方法には、新規ユーザー登録のタスクを完了することが含まれます。毎日チェックインしてください。割り当てられた小説の章を読みます。指定した小説の章にコメントを残してください。友達を招待して登録してください。ソーシャル プラットフォームで小説を共有します。

中国本土でXT.COM取引所アカウントを登録するにはどうすればよいですか? 中国本土でXT.COM取引所アカウントを登録するにはどうすればよいですか? Aug 16, 2024 pm 06:51 PM

本土のユーザーは、次の手順で XT.COM 取引所に登録できます。 XT.COM 公式 Web サイトにアクセスします。右上隅の「登録」ボタンをクリックします。 「モバイル登録」オプションを選択します。本土の携帯電話番号を入力し、確認コードを取得して入力します。パスワードを設定します。認証を完了します。登録が完了しました。

Douyinに複数のアカウントを登録するにはどうすればよいですか?複数のアカウントを管理するにはどうすればよいですか? Douyinに複数のアカウントを登録するにはどうすればよいですか?複数のアカウントを管理するにはどうすればよいですか? Apr 30, 2024 pm 01:25 PM

Douyin プラットフォームでは、多くのユーザーがさまざまなニーズを満たすために複数のアカウントを登録したいと考えています。では、Douyin に複数のアカウントを登録するにはどうすればよいでしょうか?登録後にこれらのアカウントを管理するにはどうすればよいですか?この記事では、ユーザーが Douyin プラットフォームをよりよく理解し、使用できるように、これら 2 つの問題について検討します。 1.Douyinに複数のアカウントを登録するにはどうすればよいですか? Douyin アカウントの登録: まず、ユーザーは携帯電話番号または電子メール アドレスを使用して Douyin アカウントを登録する必要があります。登録手続きでは、名前、性別、年齢などの個人情報を入力する必要があります。複数のアカウントを登録する: 最初のアカウントを登録した後、ユーザーは携帯電話番号または電子メールを介して新しいアカウントを再度登録できます。各アカウントの登録情報は、名前、性別、年齢など独立したものとする必要があります。 3. 注意事項: 複数のアカウントを登録する場合、ユーザーは以下の点に注意する必要があります。

See all articles