Table of Contents
问题内容
解决方法
Home Backend Development Golang Incorrect Postgres data type passed to query from Gorm

Incorrect Postgres data type passed to query from Gorm

Feb 15, 2024 pm 12:06 PM
User registration

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

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

问题内容

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

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

alloweddomains        []string `gorm:"type:text[];default:null" json:"alloweddomains" binding:"required"`
Copy after login

使用 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
    }
}
Copy after login

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

首先,当 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"
Copy after login

其次,当 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)
Copy after login

当我设置断点并在序列化后分析 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
    }
}
Copy after login

The above is the detailed content of Incorrect Postgres data type passed to query from Gorm. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to register railway 12306 email address How to register railway 12306 email address Apr 30, 2024 am 11:33 AM

The steps to register the Railway 12306 email address are as follows: Visit the 12306 website and click "Register"; select "Email Registration" and fill in the email, name, mobile phone and other information; set the password and security questions according to the prompts; enter the email verification code and mobile phone verification code for verification Information; click "Complete Registration".

Why can't I register at the Bitget Wallet exchange? Why can't I register at the Bitget Wallet exchange? Sep 06, 2024 pm 03:34 PM

There are various reasons for being unable to register for the BitgetWallet exchange, including account restrictions, unsupported regions, network issues, system maintenance and technical failures. To register for the BitgetWallet exchange, please visit the official website, fill in the information, agree to the terms, complete registration and verify your identity.

Why does Douyin have two accounts? How to install two TikToks on your mobile phone? Why does Douyin have two accounts? How to install two TikToks on your mobile phone? May 06, 2024 pm 09:28 PM

In the digital age, social media has become an integral part of people's lives. Douyin, as one of the most popular short video platforms in China, has attracted a large number of users. Some users even registered two accounts. So, why does Douyin have two accounts? This article will answer this question for you and explain how to install two Douyin accounts on your phone. 1. Why does Douyin have two accounts? Functional differentiation: Some users will differentiate accounts based on content type or function. For example, one account is used to share daily life, and another account is used to demonstrate professional skills. 2. Privacy protection: Some users hope to protect their privacy through two accounts, separate life and work, and avoid information leakage. 3. Interaction needs: Some users may register two due to interaction needs

What is the detailed explanation of Douyin's spark color changing rules? Various spark colors meet conditions What is the detailed explanation of Douyin's spark color changing rules? Various spark colors meet conditions May 04, 2024 am 09:31 AM

In order to enhance user interaction and improve user experience, the Douyin platform has launched Spark, an interesting interactive mechanism. Users can activate and upgrade their sparks through a series of actions on Douyin. Different colors represent different achievements and honors. Understanding the color changing rules of Douyin Spark can help users better participate and interact, and enjoy the social fun brought by Douyin. 1. What is the detailed explanation of Douyin’s spark color changing rules? 1. Behavior activates users’ interactive behaviors, such as likes, comments, shares, etc., which can activate sparks. 2. Level improvement As user interaction increases, the sparks will gradually upgrade and the color will change accordingly. 3. Color change The color change of sparks is usually related to the user's interaction frequency, interaction quality, and enthusiasm for participating in activities. 4. The task is completed

DeepSeek official website entrance and latest promotional activities DeepSeek official website entrance and latest promotional activities Feb 19, 2025 pm 05:15 PM

DeepSeek's official website is now launching multiple discount activities to provide users with a shopping experience. New users sign up to get a $10 coupon, and enjoy a 15% limited time discount for the entire audience. Recommend friends can also earn rewards, and you can accumulate points for redemption of gifts when shopping. The event deadlines are different. For details, please visit the DeepSeek official website for inquiries.

How to complete tasks in Tomato novel How to complete tasks in Tomato novel May 03, 2024 am 02:27 AM

You can earn coins and points by completing tasks on Tomato Novels. Methods include: completing new user registration tasks. Check in daily. Read the assigned novel chapter. Leave a comment on the specified novel chapter. Invite friends to register. Share novels on social platforms.

How to register XT.COM exchange account in mainland China? How to register XT.COM exchange account in mainland China? Aug 16, 2024 pm 06:51 PM

Mainland users can register on the XT.COM exchange through the following steps: Visit the XT.COM official website. Click the "Register" button in the upper right corner. Select the "Mobile Registration" option. Enter your mainland mobile phone number, obtain and enter the verification code. Set a password. Complete authentication. Registration completed.

How to register multiple accounts on Douyin? How to manage multiple accounts? How to register multiple accounts on Douyin? How to manage multiple accounts? Apr 30, 2024 pm 01:25 PM

On the Douyin platform, many users may want to register multiple accounts to meet different needs. So, how to register multiple accounts on Douyin? How to manage these accounts after registration? This article will explore these two issues to help users better understand and use the Douyin platform. 1. How to register multiple accounts on Douyin? Douyin account registration: First, users need to register a Douyin account through their mobile phone number or email address. During the registration process, you need to fill in personal information, such as name, gender, age, etc. Register multiple accounts: After registering the first account, users can register a new account again through their mobile phone number or email. The registration information for each account needs to be kept independent, such as name, gender, age, etc. 3. Notes: When registering multiple accounts, users need to pay attention to the following points: a.

See all articles