Age()函数在time.Time中无法正常工作。

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

Age() function not working with time.Time

问题

尝试使用PostgreSQL的age()函数与DateOfBirth一起使用,但出现了错误。错误信息是"Unsupported Scan, storing driver.Value type []uint8 into type *time.Time"。

如果我将DOB作为字符串传递,age()函数可以正常工作。但是,我想检查DOB的有效性,所以我使用了time.Parse("2006-01-02", DOB)函数。

在createPerson函数中,我解析了表单数据并获取了dob字段的值。然后,我使用time.Parse("2006-01-02", dob)将其转换为时间类型。

在getPerson函数中,我将URL参数id转换为整数,并使用models.person.Get(id)获取相应的person对象。

以上是要翻译的内容。

英文:

Trying to use age() function from postgresql with DateOfBirth

type Person struct {
  ID int
  DOB time.Time
}
query := `SELECT id, AGE(dateofbirth) from person WHERE id = $1`

But got an error
> Unsupported Scan, storing driver.Value type []uint8 into type *time.Time

The age() function work if I just pass the DOB as string

type Person struct {
  ID int
  DOB string
}

But I want to check the validity of DOB so I use time.Parse("2006-01-02", DOB)

func createPerson(w http.ResponseWriter, r *http.Request) {
  err := r.ParseForm()
  if err != nil {
        log.Fatal(err)
  }
  dob := r.PostForm.Get("dob")
  birthday, _ := time.Parse("2006-01-02", dob)

  err = models.person.Insert(birthday)
  if err != nil {
        log.Fatal("Server Error: ", err)
        return
  }
  http.Redirect(w, r, "/", http.StatusSeeOther)
}

func getPerson(w http.ResponseWriter, r *http.Request) {
  id, err := strconv.Atoi(chi.URLParam(r, "id"))
  if err != nil {
	log.Fatal("Not found", err)
	return
  }
  person, err = models.person.Get(id)
  if err != nil {
      log.Fatal("Server Error: ", err)
      return
  }
  render.HTML(w, http.StatusOK, "person.html", person)
}

答案1

得分: 0

你的数据库驱动程序负责将来自数据库的数据转换为Go数据类型。我假设你正在使用pq驱动程序,它有以下关于数据类型的规则:

  • 小整数类型smallint、整数类型integer和大整数类型bigint会被返回为int64类型。
  • 浮点数类型real和double precision会被返回为float64类型。
  • 字符类型char、varchar和text会被返回为string类型。
  • 日期时间类型date、time、timetz、timestamp和timestamptz会被返回为time.Time类型。
  • 布尔类型会被返回为bool类型。
  • bytea类型会被返回为[]byte类型。

所有其他类型会直接从后端以文本格式返回为[]byte值。

在PostgreSQL中,AGE函数返回的数据类型是interval。这不是直接支持的数据类型之一,所以pq将其处理为[]byte。这就是为什么当你将DOB设置为string时它能正常工作。在Go中,[]bytestring之间的转换非常简单,所以驱动程序能够填充该值。

驱动程序无法将[]byte填充到time.Time值中,因为它不知道要使用哪个转换程序。实际上,没有直接的转换程序,因为interval表示的是一段时间的持续时间,而time.Time表示的是时间的实例。interval更类似于time.Duration值。然而,驱动程序不支持从interval到任何类型的自动转换,我也不知道如何添加新的转换方式。你需要在从数据库获取数据后自己实现转换。

你也可以切换到pgx驱动程序,它支持Interval类型。

英文:

Your database driver is responsible for transforming the incoming data from the database into Go data types. I'll assume you're using pq, which has the following rules about data types:

> This package returns the following types for values from the PostgreSQL backend:
>
> - integer types smallint, integer, and bigint are returned as int64
> - floating-point types real and double precision are returned as float64
> - character types char, varchar, and text are returned as string
> - temporal types date, time, timetz, timestamp, and timestamptz are returned as time.Time
> - the boolean type is returned as bool
> - the bytea type is returned as []byte
>
> All other types are returned directly from the backend as []byte values in text format.

In PostgreSQL, the AGE function returns data type interval. This is not one of the directly supported data types, so pq processes it as []byte. That is why it works when you make DOB a string. Conversion between []byte and string in Go is trivial, so the driver is able to fill in the value.

The driver fails to fill the []byte into a time.Time value because it doesn't know what conversion routine to use. Actually, there is no direct conversion routine because interval represents a duration of time, while time.Time represents an instance of time. interval is more analogous to a time.Duration value. Still, the driver doesn't support any automatic conversion from interval to any type, and I'm not aware of a way to add a new conversion. You would have to implement the conversion yourself after fetching the data from the database.

You could also switch to the pgx driver, which supports an Interval type.

huangapple
  • 本文由 发表于 2022年11月24日 09:35:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/74554722.html
匿名

发表评论

匿名网友

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

确定