Heim > Backend-Entwicklung > Golang > Gorm gibt einen Scannerfehler für den benutzerdefinierten Zeichenfolgentyp zurück

Gorm gibt einen Scannerfehler für den benutzerdefinierten Zeichenfolgentyp zurück

王林
Freigeben: 2024-02-11 18:21:21
nach vorne
1156 Leute haben es durchsucht

Gorm 在自定义字符串类型上返回扫描仪错误

Einführung in die Banane des PHP-Editors: Wenn Sie in Gorm versuchen, einen Scanvorgang für einen benutzerdefinierten Zeichenfolgentyp durchzuführen, können Fehler auftreten. Dieses Problem kann dazu führen, dass der Scanner die Zeichenfolge nicht richtig analysiert, was zu Programmfehlern führt. Dies liegt daran, dass Gorm standardmäßig die Methode „Scan“ verwendet, um Felder vom Typ „String“ zu scannen. Bei benutzerdefinierten String-Typen verarbeitet die Methode „Scan“ dies jedoch möglicherweise nicht korrekt. Die Lösung für dieses Problem besteht darin, die Zeichenfolge mithilfe der Methode „Value“ manuell zu analysieren, um sicherzustellen, dass das Programm ordnungsgemäß ausgeführt wird. Auf diese Weise können Sie Probleme mit Scannerfehlern bei der Verwendung von Gorm vermeiden.

Frageninhalt

Ich habe folgende Entitäten geschrieben:

type datacategory string

const (
    datacategory1 datacategory = "category1"
    datacategory2 datacategory = "category2"
)

type data struct {
    name            string         `json:"name"`
    categories      []datacategory `json:"category" gorm:"type:text[]"`
}
Nach dem Login kopieren

Ich habe manuell eine Zeile in der Datenbank erstellt und den Array-Typ „Kategorien“ mit Kategorie1 und Kategorie2 gefüllt.

Aber beim Auslesen der Daten tritt folgender Fehler auf:

sql: scan error on column index 19, name "category": unsupported scan, storing driver.value type string into type *[]datacategory
Nach dem Login kopieren

Beispielwertmethode:

func (s DataCategorySlice) Value() (driver.Value, error) {
    if s == nil {
        return nil, nil
    }
    if len(s) == 0 {
        return "{}", nil
    }

    v := []string{}
    for _, dc := range s {
        v = append(v, string(dc))
    }
    result := fmt.Sprintf("{%s}", strings.Join(v, ","))
    return result, nil
}
Nach dem Login kopieren

Problemumgehung

Das folgende Beispiel geht davon aus, dass Sie Postgresql als RDBMS verwenden und der datacategory-Wert keine Kommas oder einfache Anführungszeichen ohne Escapezeichen enthält.

// declare the custom type
type datacategoryslice []datacategory
Nach dem Login kopieren
// implement driver.valuer to encode the value into the
// correct format that is accepted by the target rdbms
func (s datacategoryslice) value() (driver.value, error) {
    if s == nil {
        return nil, nil
    }
    if len(s) == 0 {
        return []byte(`{}`), nil
    }

    v := []byte(`{`)
    for i := range s {
        v = append(v, s[i]...)
        v = append(v, ',')
    }
    v[len(v)-1] = '}' // replace last comma with closing brace
    return v, nil
}
Nach dem Login kopieren
// implement scanner to decode the raw source
// value as retrieved from the database
func (s *datacategoryslice) scan(src any) error {
    var data []byte
    switch v := src.(type) {
    case []byte:
        data = v
    case string:
        data = []byte(v)
    case nil:
        return nil
    default:
        return fmt.errorf("unsupported type: %t", src)
    }
    if len(data) == 0 {
        return nil
    }
    data = data[1:len(data)-1] // remove surrounding braces
    for _, v := range bytes.split(data, []byte{','}) {
        *s = append(*s, datacategory(v))
    }
    return nil
}
Nach dem Login kopieren

Oder, wenn von value() (driver.value, error) 返回 <code>[]byte 不起作用,例如它会导致 “错误:格式错误的数组文字:<hex 字段值的表示形式> (sqlstate 22p02)”,那么您可以尝试使用 string als Rückgabetyp.

Beispiel von @kozhioyrin

// implement driver.Valuer to encode the value into the
// correct format that is accepted by the target RDBMS
func (s DataCategorySlice) Value() (driver.Value, error) {
    if s == nil {
        return nil, nil
    }
    if len(s) == 0 {
        return "{}", nil
    }

    v := []string{}
    for _, dc := range s {
        v = append(v, string(dc))
    }
    result := fmt.Sprintf("{%s}", strings.Join(v, ","))
    return result, nil
}
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonGorm gibt einen Scannerfehler für den benutzerdefinierten Zeichenfolgentyp zurück. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage