登录
首页 >  Golang >  Go问答

在服务器上加载 CSV 数据,将数据转换为 JSON 并使用 Golang 使用 Json 查询获取结果

来源:stackoverflow

时间:2024-04-19 08:18:37 255浏览 收藏

各位小伙伴们,大家好呀!看看今天我又给各位带来了什么文章?本文标题《在服务器上加载 CSV 数据,将数据转换为 JSON 并使用 Golang 使用 Json 查询获取结果》,很明显是关于Golang的文章哈哈哈,其中内容主要会涉及到等等,如果能帮到你,觉得很不错的话,欢迎各位多多点评和分享!

问题内容

我正在尝试构建一个 tcp 服务器,从 csv 文件加载数据集并提供查询数据集的接口。 tcp 服务器将公开端口 4040。csv 文件包含与冠状病毒案例相关的以下列:

  • 累计检测呈阳性
  • 执行的累积测试
  • 日期
  • 出院
  • 已过期
  • 已录取
  • 地区 用户应该能够在基于 linux/unix 的系统上使用 netcat nc localhost 4040 命令连接到服务器。

连接到 tcp 后,用户应该能够通过发送 json 格式的查询来与应用程序进行通信。

{
    "query": {
        "region": "sindh"
    }
}
{
    "query": {
        "date": "2020-03-20"
    }
}

我的server.go

package main

import (
    "fmt"
    "net"
    "os"
    "flag"
    "log"
    "encoding/csv"
    "encoding/json"
    "bufio"
    "io"
    "strings"
)

type CovidPatient struct {
    Positive    string      `json:"Covid_Positive"`
    Performed   string      `json:"Coivd_Performed"`
    Date        string      `json:"Covid_Date"`
    Discharged  string      `json:"Covid_Discharged"`
    Expired     string      `json:"Covid_Expired"`
    Region      string      `json:"Covid_Region"`
    Admitted    string      `json:"Covid_Admitted"`
}

type DataRequest struct {   
    Get string `json:"get"`
}

type DataError struct {     
    Error string `json:"Covid_error"`
}

func Load(path string) []CovidPatient {
    table := make([]CovidPatient, 0)
    var patient CovidPatient
    file, err := os.Open(path)
    if err != nil {
        panic(err.Error())
    }
    defer file.Close()

    reader := csv.NewReader(file)
    csvData, err := reader.ReadAll()
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    for _, row := range csvData{
        patient.Positive =  row[0]
        patient.Performed =  row[1]
        patient.Date =       row[2]
        patient.Discharged = row[3]
        patient.Expired =    row[4]
        patient.Region =     row[5]
        patient.Admitted =   row[6]
        table = append(table, patient)
    }
    return table
}

func Find(table []CovidPatient, filter string) []CovidPatient {
    if filter == "" || filter == "*" {
        return table
    }
    result := make([]CovidPatient, 0)
    filter = strings.ToUpper(filter)
    for _, cp := range table {
        if cp.Date == filter ||
            cp.Region == filter ||
            strings.Contains(strings.ToUpper(cp.Positive), filter)      ||
            strings.Contains(strings.ToUpper(cp.Performed), filter)     ||
            strings.Contains(strings.ToUpper(cp.Date), filter)          ||
            strings.Contains(strings.ToUpper(cp.Discharged), filter)    ||
            strings.Contains(strings.ToUpper(cp.Expired), filter)       ||
            strings.Contains(strings.ToUpper(cp.Region), filter)        ||
            strings.Contains(strings.ToUpper(cp.Admitted), filter){
            result = append(result, cp)
        }
    }
    return result
}

var (
    patientsDetail = Load("./covid_final_data.csv")
)

func main(){
    var addr string
    var network string
    flag.StringVar(&addr, "e", ":4040", "service endpoint [ip addr or socket path]")
    flag.StringVar(&network, "n", "tcp", "network protocol [tcp,unix]")
    flag.Parse()

    switch network {
    case "tcp", "tcp4", "tcp6", "unix":
    default:
        fmt.Println("unsupported network protocol")
        os.Exit(1)
    }

    ln, err := net.Listen(network, addr)
    if err != nil {
        log.Println(err)
        os.Exit(1)
    }
    defer ln.Close()
    log.Println("Covid19 Condition in Pakistan")
    log.Printf("Service started: (%s) %s\n", network, addr)
    
    for {
        conn, err := ln.Accept()
        if err != nil {
            log.Println(err)
            conn.Close()
            continue
        }
        log.Println("Connected to ", conn.RemoteAddr())
        go handleConnection(conn)
    }
}
func handleConnection(conn net.Conn) {
    defer func() {
        if err := conn.Close(); err != nil {
            log.Println("error closing connection:", err)
        }
    }()

    reader := bufio.NewReaderSize(conn, 4)

    for {
        buf, err := reader.ReadSlice('}')
        if err != nil {
            if err != io.EOF {
                log.Println("connection read error:", err)
                return
            }
        }
        reader.Reset(conn)
        
        var req DataRequest
        if err := json.Unmarshal(buf, &req); err != nil {
            log.Println("failed to unmarshal request:", err)
            cerr, jerr := json.Marshal(DataError{Error: err.Error()})
            if jerr != nil {
                log.Println("failed to marshal DataError:", jerr)
                continue
            }
            if _, werr := conn.Write(cerr); werr != nil {
                log.Println("failed to write to DataError:", werr)
                return
            }
            continue
        }

        result := Find(patientsDetail, req.Get)

        rsp, err := json.Marshal(&result)
        if err != nil {
            log.Println("failed to marshal data:", err)
            if _, err := fmt.Fprintf(conn, `{"data_error":"internal error"}`); err != nil {
                log.Printf("failed to write to client: %v", err)
                return
            }
            continue
        }
        if _, err := conn.Write(rsp); err != nil {
            log.Println("failed to write response:", err)
            return
        }
    }
}

这会正确加载 csv 并将其转换为 json。但是,当我尝试使用 netcat 命令运行查询时,它返回空 json 元素。请指导我哪里有错误。


解决方案


我猜你想要这个:

╭─root@desktop-ocdrd7q ~
╰─# nc localhost 4040
{"get": "sindh"}
[{"covid_positive":"1","coivd_performed":"1","covid_date":"1","covid_discharged":"1","covid_expired":"1","covid_region":"sindh","covid_admitted":"1"}]

你应该做的只是修改你的 json 请求。

package main

import (
    "bufio"
    "encoding/csv"
    "encoding/json"
    "flag"
    "fmt"
    "io"
    "log"
    "net"
    "os"
)

type covidpatient struct {
    positive   string `json:"covid_positive"`
    performed  string `json:"coivd_performed"`
    date       string `json:"covid_date"`
    discharged string `json:"covid_discharged"`
    expired    string `json:"covid_expired"`
    region     string `json:"covid_region"`
    admitted   string `json:"covid_admitted"`
}

type datarequest struct {
    get covidpatient `json:"get"`
}

type dataerror struct {
    error string `json:"covid_error"`
}

func load(path string) []covidpatient {
    table := make([]covidpatient, 0)
    var patient covidpatient
    file, err := os.open(path)
    if err != nil {
        panic(err.error())
    }
    defer file.close()

    reader := csv.newreader(file)
    csvdata, err := reader.readall()
    if err != nil {
        fmt.println(err)
        os.exit(1)
    }
    for _, row := range csvdata {
        patient.positive = row[0]
        patient.performed = row[1]
        patient.date = row[2]
        patient.discharged = row[3]
        patient.expired = row[4]
        patient.region = row[5]
        patient.admitted = row[6]
        table = append(table, patient)
    }
    return table
}

func find(table []covidpatient, filter covidpatient) []covidpatient {

    result := make([]covidpatient, 0)

    log.println(filter, table)

    for _, cp := range table {

        if filter.positive == "" {
        } else if filter.positive != cp.positive {
            continue
        }
        if filter.performed == "" {
        } else if filter.performed != cp.performed {
            continue
        }
        if filter.date == "" {
        } else if filter.date != cp.date {
            continue
        }
        if filter.discharged == "" {
        } else if filter.discharged != cp.discharged {
            continue
        }
        if filter.expired == "" {
        } else if filter.expired != cp.expired {
            continue
        }
        if filter.region == "" {
        } else if filter.region != cp.region {
            continue
        }
        if filter.admitted == "" {
        } else if filter.admitted != cp.admitted {
            continue
        }

        result = append(result, cp)
    }
    return result

}

var (
    patientsdetail = load("./covid_final_data.csv")
)

func main() {
    log.setflags(log.lshortfile | log.ltime)
    var addr string
    var network string
    flag.stringvar(&addr, "e", ":4040", "service endpoint [ip addr or socket path]")
    flag.stringvar(&network, "n", "tcp", "network protocol [tcp,unix]")
    flag.parse()

    switch network {
    case "tcp", "tcp4", "tcp6", "unix":
    default:
        fmt.println("unsupported network protocol")
        os.exit(1)
    }

    ln, err := net.listen(network, addr)
    if err != nil {
        log.println(err)
        os.exit(1)
    }
    defer ln.close()
    log.println("covid19 condition in pakistan")
    log.printf("service started: (%s) %s\n", network, addr)

    for {
        conn, err := ln.accept()
        if err != nil {
            log.println(err)
            conn.close()
            continue
        }
        log.println("connected to ", conn.remoteaddr())
        go handleconnection(conn)
    }
}
func handleconnection(conn net.conn) {
    defer func() {
        if err := conn.close(); err != nil {
            log.println("error closing connection:", err)
        }
    }()

    reader := bufio.newreadersize(conn, 100)

    for {
        buf, err := reader.readbytes('|')
        if err != nil {
            if err != io.eof {
                log.println("connection read error:", err)
                return
            }
        }
        reader.reset(conn)

        var req datarequest
        if err := json.unmarshal(buf[:len(buf)-1], &req); err != nil {
            log.println("failed to unmarshal request:", string(buf), err)
            cerr, jerr := json.marshal(dataerror{error: err.error()})
            if jerr != nil {
                log.println("failed to marshal dataerror:", jerr)
                continue
            }
            if _, werr := conn.write(cerr); werr != nil {
                log.println("failed to write to dataerror:", werr)
                return
            }
            continue
        }

        result := find(patientsdetail, req.get)

        rsp, err := json.marshal(&result)
        if err != nil {
            log.println("failed to marshal data:", err)
            if _, err := fmt.fprintf(conn, `{"data_error":"internal error"}`); err != nil {
                log.printf("failed to write to client: %v", err)
                return
            }
            continue
        }
        if _, err := conn.write(rsp); err != nil {
            log.println("failed to write response:", err)
            return
        }
    }
}

查询是:

╭─root@DESKTOP-OCDRD7Q ~
╰─# nc localhost 4040                                                                                             127 ↵
{
    "get": {
        "Covid_Region": "Sindh",
        "Covid_Date": "2020-03-20"
    }
}|
[{"Covid_Positive":"1","Coivd_Performed":"1","Covid_Date":"2020-03-20","Covid_Discharged":"1","Covid_Expired":"1","Covid_Region":"Sindh","Covid_Admitted":"1"}]

以上就是《在服务器上加载 CSV 数据,将数据转换为 JSON 并使用 Golang 使用 Json 查询获取结果》的详细内容,更多关于的资料请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>