2017-05-10 12 views
0

まだ正規化されていないデータベースで作業していますが、このテーブルには40を超える列のレコードが含まれています。私はこのコードを呼び出すと、Scanは、それが「42個のデスティネーション引数ではなく、1を期待」と文句を言いGoの構造体に大きな行をスキャンする

type Coderyte struct { 
    ID int `json:"id"` 
    EmrID int `json:"emr_id"` 
    DftID int `json:"dft_id"` 

    Fix int `json:"fix"` 
    ReportDate string `json:"report_date"` // Time? 
    Patient string `json:"patient"` 
    ... // etc 
} 
func ReadCoderyte(res http.ResponseWriter, req *http.Request) { 
    rows, err := db.Query("SELECT * FROM coderyte") 
    if err != nil { 
    http.Error(res, "Error querying database", 500) 
    } 
    defer rows.Close() 

    // Convert rows into a slice of Coderyte structs 
    coderytes := make([]*Coderyte, 0) 
    for rows.Next() { 
    coderyte := new(Coderyte) 
    err := rows.Scan(&coderyte) // Expected 42 columns 
    if err != nil { 
     panic(err) 
     http.Error(res, "Error converting coderyte object", 500) 
    } 
    coderytes = append(coderytes, coderyte) 
    } 

:以下

大きな構造体にレコードをスキャンする(しよう)のための私のGoコードです。私の理解では、私の検索すなわちScan(&coderyte.ID, &coderyte.EmrID, etc)

、私はスキャン呼び出しの内部で、この大規模な構造体のすべての単一のフィールドに対処する必要があるだろうということですのみを示唆答えはsqlxを使用することですthis other questionを、得られています。サードパーティのツールを使用しないようにしたい場合は、サードパーティのツールを使用しないようにしています。

私の質問は次のようになっています:大規模なデータベースレコードをすべての単一フィールドを指定せずに構造体に変換する方法はありますか?

この関数の最終目標はオブジェクトのJSON配列を返すことですが、重要ではないと感じてコードのその部分は含めませんでした。 ScanをバイパスしてJSONを返す方法がある場合は、それも分かります。

+2

短い回答:いいえ。 長い答え:sqlxもお勧めします。標準ライブラリは、構造体へのアンマーシャリングをサポートしていません。 –

+0

私と同じ勧告もあります。 – RayfenWindspear

+0

これはサポートされていませんが、まだ標準のsqlパッケージを使用したい場合は、http://go-database-sql.org/retrieving.html –

答えて

2

この機能の究極の目標は、オブジェクト

のJSON配列を返すことですあなたは完全にその後、構造体をビアス、代わりにmap[string]interface{}にスキャンし、かなり動的にそれをすべて行うことができますように聞こえます: あなたはこのような何か行うことができます:あなたはJSONを取り、json.Unmarshalを行うことができますので、明らかにあなたはまた、構造体に変換することができ、今

rows, _ := db.Query("SELECT * FROM coderyte") 
cols, _ := rows.Columns() 
store := []map[string]interface{} 
for rows.Next() { 
    columns := make([]interface{}, len(cols)) 
    columnPointers := make([]interface{}, len(cols)) 
    for i, _ := range columns { 
     columnPointers[i] = &columns[i] 
    } 

    if err := rows.Scan(columnPointers...); err != nil { 
     return err 
    } 
    m := make(map[string]interface{}) 
    for i, colName := range cols { 
     val := columnPointers[i].(*interface{}) 
     m[colName] = *val 
    } 
    store = append(store, m)   
} 
js, _ := json.Marshal(store) 
fmt.Println(string(js)) 

を、しかし、あなたのユースケースTHAを与えられました無意味な余分なステップのように思える。

js, _ := json.Marshal(store) 
structs := []Coderyte{} 
json.Unmarshal(js, &structs) 

すべてのことが言われて、あなたはおそらくSQLXを使用する必要があります - 彼らはおそらく道賢いことを行うと方法より効率的にそれを行います。

+0

私はちょうど上司と話しました。彼は上司と同じデータを使っていたときに 'sqlx'を使っていることを明らかにしました。私はこのソリューションを試していますが、今はデータのJSON表現だけが必要ですが、おそらく他のコメントや推奨事項に従って 'sqlx 'に移ります。ありがとう! – Avery

関連する問題