如何将 SQL 输出格式化为 JSON?

huangapple go评论79阅读模式
英文:

How to format sql output into json

问题

我有一个查询数据库并返回两列的Go函数:

var colA string
var colB string

err = db.QueryRow("select colA, colB from table where colA = %v", 1).Scan(&colA,&colB)
if err != nil {
    fmt.Printf(err.Error())
}
fmt.Println(colA,colB)

return nil

我想以JSON格式返回输出,例如{colA:colB}。我尝试使用json.Marshal函数,但无法正确运行。

英文:

I have a Go function that queries a database and returns two columns:

var colA string
var colB string

	err = db.QueryRow("select colA, colB from table where colA = %v", 1).Scan(&colA,&colB)
	if err != nil {
		fmt.Printf(err.Error())
	}
	fmt.Println(colA,colB)

	return nil

I would like to return the output in json format like {colA:colB}. I have played around with the json.Marshal function but can't get it working correctly.

答案1

得分: 1

你可以使用结构体来定义数据的结构,例如:

type User struct {
    Username string `json:"username"`
    Email    string `json:"email"`
}

然后在查询时使用该结构体:

user := User{}
err = db.QueryRow("select colA, colB from table where colA = %v", 1).Scan(&user.Username, &user.Email)
if err != nil {
    fmt.Printf(err.Error())
}

之后可以调用json.Marshal将其转换为JSON字符串:

msg, err := json.Marshal(user)
if err != nil {
    log.Println(err)
}

fmt.Println(string(msg)) // "{\"username\":\"Blah\",\"email\":\"asd@asd.com\"}"

另外,如果你在调用Marshal时使用的是一个结构体,那么结构体的字段必须是可导出的,即字段名的首字母必须大写,才能被json.Marshal处理。

关于json.Marshal的更多信息,你可以参考官方文档:https://golang.org/pkg/encoding/json/#Marshal

英文:

You could make a struct if you know what your data is going to be: e.g

type User struct {
    Username string `json:"username"`
    Email    string `json:"email"`
}

Then on your query:

user := User{}
err = db.QueryRow("select colA, colB from table where colA = %v", 1).Scan(&user.Username,&user.Email)
    if err != nil {
        fmt.Printf(err.Error())
}

Then call marshal on it

msg, err := json.Marshal(user)
if err != nil {
    log.Println(err)
}

fmt.Println(string(msg)) // "{ "username": "Blah", "email": "asd@asd.com" }"

Also with the json.Marshal package if you're calling Marshal on a struct your fields MUST be exported by using a capital first letter on the field name, e.g. Username

> // Field is ignored by this package. Field int json:"-"
>
> // Field appears in JSON as key "myName". Field int json:"myName"
>
> // Field appears in JSON as key "myName" and // the field is omitted
> from the object if its value is empty, // as defined above. Field int
> json:"myName,omitempty"
>
> // Field appears in JSON as key "Field" (the default), but // the
> field is skipped if empty. // Note the leading comma. Field int
> json:",omitempty"

https://golang.org/pkg/encoding/json/#Marshal

答案2

得分: 0

你可以创建一个只有一个元素的映射,并将其编组:

m := map[string]string{colA: colB}
b, err := json.Marshal(m)

完整示例:https://play.golang.org/p/ntT5h3oHvY

英文:

You can create a one element map and marshal it:

m := map[string]string{colA: colB}
b, err := json.Marshal(m)

Full example: https://play.golang.org/p/ntT5h3oHvY

答案3

得分: 0

我建议你研究一些数据库管理框架。

我个人使用gorm (github.com/jinzhu/gorm) 来满足我的数据库需求。它具有使用结构体自动创建数据库并解析的功能。

你可以配合 "encoding/json" 包将数据转换为json格式并存入数据库,或者从数据库中取出并转换为json格式。

以下是一些你可以参考的个人代码:

结构体

type Application struct {
  Id       		int64 			`json:"id"`
  UserID    	int64			`sql:"not null;" json:"user_id"`
  Name	 		string			`sql:"size:255; not null; unique;" json:"name"`
  ExposedPorts	string			`json:"exposed_ports"` //docker
  DockerImage	string			`sql:"size:255; not null;" json:"docker_image"`
  Dependencies 	string 			`json:"dependencies"`  
  IsEnabled		bool 			`sql:"default:true" json:"is_enabled"`

}

JSON:

func (a *Application) GetJSON() (string, error) {
	b, err := json.Marshal(a)
    if err != nil {
        logging.Log(err)
        return "",err;
    }
    return string(b),err;
}

数据库

    //获取应用程序信息
func GetApplication(id int64) (*models.Application, error) {
 app := &models.Application{}

 err := db.Where(&models.Application{Id: id}).First(&app).Error

 return app, err
}

func GetApplications() ([]models.Application, error) {
    //返回所有应用程序的列表
    apps := []models.Application{}

    err := db.Find(&apps).Error

    return apps, err
}

//从数据库中删除应用程序
func DeleteApplication(id int64) (bool, error) {
    logging.Log("Deleting Application: ", id)

    app := models.Application{}

    err := db.Where(&models.Application{Id: id}).First(&app).Error 

    if err != nil {
        return false, err
    }
    //  TODO: 检查权限
    //      删除所有容器

    //从数据库中删除应用程序
    err = db.Delete(&app).Error

    if err != nil {
       return false, err
    }

    return true, err

}

//更新应用程序
func UpdateApplication(app *models.Application) (bool, error) {

    newapp := models.Application{}
    err := db.Where(&models.Application{Id: app.Id}).First(&newapp).Error 

    if err != nil {
       return false, err
    }

    err = db.Save(&app).Error

    if err != nil {
        return false, err
    }

    return true, nil
} 

希望对你有所帮助 如何将 SQL 输出格式化为 JSON?

英文:

I'd suggest looking into some database management frameworks.

I personally use gorm (github.com/jinzhu/gorm) for my database needs. It has functionality for automatically creating your database using structs and parsing them back out again.

You can pair that with the "encoding/json" package to take it to/from json to/from your database.

Here's some personal code you can use for reference:

Struct:

type Application struct {
  Id       		int64 			`json:"id"`
  UserID    	int64			`sql:"not null;" json:"user_id"`
  Name	 		string			`sql:"size:255; not null; unique;" json:"name"`
  ExposedPorts	string			`json:"exposed_ports"` //docker
  DockerImage	string			`sql:"size:255; not null;" json:"docker_image"`
  Dependencies 	string 			`json:"dependencies"`  
  IsEnabled		bool 			`sql:"default:true" json:"is_enabled"`

}

JSON:

func (a *Application) GetJSON() (string, error) {
	b, err := json.Marshal(a)
    if err != nil {
        logging.Log(err)
        return "",err;
    }
    return string(b),err;
}

Database

    //Get application information
func GetApplication(id int64) (*models.Application, error) {
 app := &models.Application{}

 err := db.Where(&models.Application{Id: id}).First(&app).Error

 return app, err
}

func GetApplications() ([]models.Application, error) {
    //Returns a list of all applications 
    apps := []models.Application{}

    err := db.Find(&apps).Error

    return apps, err
}

//delete application from database
func DeleteApplication(id int64) (bool, error) {
    logging.Log("Deleting Application: ", id)

    app := models.Application{}

    err := db.Where(&models.Application{Id: id}).First(&app).Error 

    if err != nil {
        return false, err
    }
    //  TODO: Check for auth
    //      Delete all containers

    //Delete application from database
    err = db.Delete(&app).Error

    if err != nil {
       return false, err
    }

    return true, err

}

//Update Application
func UpdateApplication(app *models.Application) (bool, error) {

    newapp := models.Application{}
    err := db.Where(&models.Application{Id: app.Id}).First(&newapp).Error 

    if err != nil {
       return false, err
    }

    err = db.Save(&app).Error

    if err != nil {
        return false, err
    }

    return true, nil
} 

Hope this helps 如何将 SQL 输出格式化为 JSON?

答案4

得分: 0

这是一个完整的示例:

campaign.model.go:

package models

import "database/sql"

// Campaign Model
type Campaign struct {
	CampaignId      int            `db:"campaign_id" json:"campaignId"`
	CampaignNme     string         `db:"campaign_nme" json:"campaignNme"`
	OrganizationId  sql.NullInt64  `db:"organization_id" json:"organizationId"`
}

campaign.repository.go:

package repositories

import (
	"github.com/jmoiron/sqlx"
	"go-clean-arch/domain/models"
	"go-clean-arch/domain/repositories"
)

type CampaignRepository struct {
	Db *sqlx.DB
}

func NewCampaignRepository(Db *sqlx.DB) repositories.CampaignRepository {
	return &CampaignRepository{Db}
}

func (cr *CampaignRepository) FindById(id string) (models.Campaign, error) {
	campaign := models.Campaign{}
	query := `
		SELECT
			campaign_id,
			campaign_nme,
			organization_id
		FROM "CAMPAIGN" WHERE campaign_id = $1
	`
	err := cr.Db.Get(&campaign, query, id)
	if err != nil {
		return campaign, err
	}
	return campaign, nil
}

main.go:

func main() {
	dbConf := database.PGDatabaseConfig{
		Host:     viper.GetString("SQL_HOST"),
		Port:     viper.GetString("SQL_PORT"),
		User:     viper.GetString("SQL_USER"),
		Password: viper.GetString("SQL_PASSWORD"),
		Dbname:   viper.GetString("SQL_DB"),
	}
	db, err := database.ConnectPGDatabase(&dbConf)
	if err != nil {
		log.Fatal(err)
	}

	defer func() {
		if err := recover(); err != nil {
			fmt.Println(err)
		}
	}()

	//userRepository := repositories.NewUserRepository(db)
	//users, _ := userRepository.FindAll()
	//fmt.Printf("%#v", &users)

	campaignRepository := repositories.NewCampaignRepository(db)
	campaign, err := campaignRepository.FindById("102")
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v", campaign)
	campaignJSON, err := json.Marshal(campaign)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(campaignJSON))

}

输出:

☁  go-clean-arch [master] ⚡  go run main.go
models.Campaign{CampaignId:102, CampaignNme:"Generic Party / Memories", OrganizationId:sql.NullInt64{Int64:0, Valid:false}}
campaignJSON: {"campaignId":102,"campaignNme":"Generic Party / Memories","organizationId":{"Int64":0,"Valid":false}}
英文:

Here is a completely sample:

campaign.model.go:

package models

import "database/sql"

// Campaign Model
type Campaign struct {
	CampaignId int `db:"campaign_id" json:"campaignId"`
	CampaignNme string `db:"campaign_nme" json:"campaignNme"`
	OrganizationId sql.NullInt64 `db:"organization_id" json:"organizationId"`
}

campaign.repository.go:

package repositories

import (
	"github.com/jmoiron/sqlx"
	"go-clean-arch/domain/models"
	"go-clean-arch/domain/repositories"
)

type CampaignRepository struct {
	Db *sqlx.DB
}

func NewCampaignRepository(Db *sqlx.DB) repositories.CampaignRepository {
	return &CampaignRepository{Db}
}

func (cr *CampaignRepository)FindById(id string) (models.Campaign, error) {
	campaign := models.Campaign{}
	query := `
		SELECT
			campaign_id,
			campaign_nme,
			organization_id
		FROM "CAMPAIGN" WHERE campaign_id = $1
	`
	err := cr.Db.Get(&campaign, query, id)
	if err != nil {
		return campaign, err
	}
	return campaign, nil
}

main.go:

func main() {
	dbConf := database.PGDatabaseConfig{
		Host: viper.GetString("SQL_HOST"),
		Port: viper.GetString("SQL_PORT"),
		User: viper.GetString("SQL_USER"),
		Password: viper.GetString("SQL_PASSWORD"),
		Dbname: viper.GetString("SQL_DB"),
	}
	db, err := database.ConnectPGDatabase(&dbConf)
	if err != nil {
		log.Fatal(err)
	}

	defer func () {
		if err := recover(); err != nil {
			fmt.Println(err)
		}
	}()

	//userRepository := repositories.NewUserRepository(db)
	//users, _ := userRepository.FindAll()
	//fmt.Printf("%#v", &users)

	campaignRepository := repositories.NewCampaignRepository(db)
	campaign, err := campaignRepository.FindById("102")
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v", campaign)
	campaignJSON, err := json.Marshal(campaign)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(campaignJSON))

}

Output:

☁  go-clean-arch [master] ⚡  go run main.go
models.Campaign{CampaignId:102, CampaignNme:"Generic Party / Memories", OrganizationId:sql.NullInt64{Int64:0, Valid:false}}
campaignJSON: {"campaignId":102,"campaignNme":"Generic Party / Memories","organizationId":{"Int64":0,"Valid":false}}

huangapple
  • 本文由 发表于 2016年1月4日 10:57:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/34584126.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定