Go Gorm提供了自动映射现有的Mysql数据库表的方法吗?

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

Does Go Gorm provide any method to auto map existing tables in Mysql database

问题

我是Go的新手。我有一个旧工具,用于检查和比较Mysql数据库中的数据与我的设备,并且我想用Go重写这个工具。

由于表和数据已经存在于Mysql中,我尝试使用GORM自动映射现有的表。但是我不确定如何做到这一点?我在GORM文档中没有找到任何关于自动映射现有表的描述。

我重新声明了现有的表模型并尝试查询数据。具体步骤如下:

例如,我的其中一个表如下所示:

MariaDB [neutron]> desc lbaas_loadbalancers;
+---------------------+--------------+------+-----+---------+-------+
| Field               | Type         | Null | Key | Default | Extra |
+---------------------+--------------+------+-----+---------+-------+
| project_id          | varchar(255) | YES  | MUL | NULL    |       |
| id                  | varchar(36)  | NO   | PRI | NULL    |       |
| name                | varchar(255) | YES  |     | NULL    |       |
| description         | varchar(255) | YES  |     | NULL    |       |
| vip_port_id         | varchar(36)  | YES  | MUL | NULL    |       |
| vip_subnet_id       | varchar(36)  | NO   |     | NULL    |       |
| vip_address         | varchar(36)  | YES  |     | NULL    |       |
| admin_state_up      | tinyint(1)   | NO   |     | NULL    |       |
| provisioning_status | varchar(16)  | NO   |     | NULL    |       |
| operating_status    | varchar(16)  | NO   |     | NULL    |       |
| flavor_id           | varchar(36)  | YES  | MUL | NULL    |       |
+---------------------+--------------+------+-----+---------+-------+
11 rows in set (0.002 sec)

MariaDB [neutron]> select * from lbaas_loadbalancers \G;
*************************** 1. row ***************************
         project_id: 346052548d924ee095b3c2a4f05244ac
                 id: f6638d02-29f8-41aa-9433-179bf49f5fbd
               name: test1
        description:
        vip_port_id: 21cebbd5-fa4c-4d20-9858-d14ba3eacea8
      vip_subnet_id: 0916f471-afcd-48ee-afc5-56bcb0efa963
        vip_address: 172.168.1.6
     admin_state_up: 1
provisioning_status: ACTIVE
   operating_status: ONLINE
          flavor_id: NULL
1 row in set (0.003 sec)

然后我尝试使用GORM映射该表。我只选择了两个字段IDName进行测试。

package main

import (
	"log"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

// 为了测试目的,只在模型中声明了两个属性
type Lbaas_loadbalancers struct {
	ID   string
	Name string
}

func main() {
	var lb Lbaas_loadbalancers
	dsn := "test:test@tcp(192.168.0.17:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Fatal("connection error")
	}

	test := db.Take(&lb)
	log.Println("test err is ", test.Error)
	log.Println(test.RowsAffected)

    // 这一行报错:./db.go:25:6: test.ID undefined (type *gorm.DB has no field or method ID)
	log.Println(test.ID)
    
    // 如果我注释掉上面的那行,这将打印出'mysql',但实际名称是'test1'。
	log.Println(test.Name())
}

最后,我运行go run db.go,我得到了以下错误:

➜  test git:(main) ✗ go run db.go
# command-line-arguments
./db.go:27:20: cannot convert test.Config.Dialector.Name (type func() string) to type string

这似乎不是正确的方法。使用GORM模块自动映射现有的Mysql数据库的正确方法是什么?

如果下面的代码是正确的方法,为什么我不能直接从db.Take方法的返回值中获取ID属性?我需要进行数据转换吗?

请给我一些提示,谢谢。

英文:

I am a newcomer to Go. I have an old tool to check and compare data in the Mysql database to my device, and I want to rewrite the tool in Go.

Since the tables and data have been already in the Mysql, I try to use GORM to auto map the existing tables. But I am not sure how to do that? I did not find any description of automapping an existing table in the GORM documentation.

I redeclare the existing table model and try to query data. The procedure is as below:

For example one of my tables is like this:

MariaDB [neutron]> desc lbaas_loadbalancers;
+---------------------+--------------+------+-----+---------+-------+
| Field               | Type         | Null | Key | Default | Extra |
+---------------------+--------------+------+-----+---------+-------+
| project_id          | varchar(255) | YES  | MUL | NULL    |       |
| id                  | varchar(36)  | NO   | PRI | NULL    |       |
| name                | varchar(255) | YES  |     | NULL    |       |
| description         | varchar(255) | YES  |     | NULL    |       |
| vip_port_id         | varchar(36)  | YES  | MUL | NULL    |       |
| vip_subnet_id       | varchar(36)  | NO   |     | NULL    |       |
| vip_address         | varchar(36)  | YES  |     | NULL    |       |
| admin_state_up      | tinyint(1)   | NO   |     | NULL    |       |
| provisioning_status | varchar(16)  | NO   |     | NULL    |       |
| operating_status    | varchar(16)  | NO   |     | NULL    |       |
| flavor_id           | varchar(36)  | YES  | MUL | NULL    |       |
+---------------------+--------------+------+-----+---------+-------+
11 rows in set (0.002 sec)

MariaDB [neutron]> select * from lbaas_loadbalancers \G;
*************************** 1. row ***************************
         project_id: 346052548d924ee095b3c2a4f05244ac
                 id: f6638d02-29f8-41aa-9433-179bf49f5fbd
               name: test1
        description:
        vip_port_id: 21cebbd5-fa4c-4d20-9858-d14ba3eacea8
      vip_subnet_id: 0916f471-afcd-48ee-afc5-56bcb0efa963
        vip_address: 172.168.1.6
     admin_state_up: 1
provisioning_status: ACTIVE
   operating_status: ONLINE
          flavor_id: NULL
1 row in set (0.003 sec)

Then I try to use GORM mapping the table. I just chosen two fields ID and Name for the test.

package main

import (
	"log"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

// declare only two attribute in the model for test purpose 
type Lbaas_loadbalancers struct {
	ID   string
	Name string
}

func main() {
	var lb Lbaas_loadbalancers
	dsn := "test:test@tcp(192.168.0.17:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Fatal("connection error")
	}

	test := db.Take(&lb)
	log.Println("test err is ", test.Error)
	log.Println(test.RowsAffected)

    // this line report error: ./db.go:25:6: test.ID undefined (type *gorm.DB has no field or method ID)
	log.Println(test.ID)
    
    // if I comment the above line, this print out 'mysql', but the actual name is 'test1'.
	log.Println(test.Name())
}

Finally, I run go run db.go, I got this error:

➜  test git:(main) ✗ go run db.go
# command-line-arguments
./db.go:27:20: cannot convert test.Config.Dialector.Name (type func() string) to type string

It seems not the right way to do it. what is the correct way to auto map an existing database in Mysql by using GORM module?

If the below code is the correct way, why I cannot get the ID attribute from the return value of db.Take method directly? Do I need to do data conversion?

Please give me some hints, thanks.

答案1

得分: 1

我知道这里出了什么问题,我不应该从db.Take的返回值中获取ID和Name,它获取的是lb变量的地址,并改变了lb。

我真是太傻了,刚刚才意识到问题。 Go Gorm提供了自动映射现有的Mysql数据库表的方法吗?

英文:

I know what is wrong here, I should not get ID and Name from the db.Take return, It takes the address of lb variable, and change the lb.

I am so silly, just realized the problem. Go Gorm提供了自动映射现有的Mysql数据库表的方法吗?

huangapple
  • 本文由 发表于 2021年11月27日 22:37:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/70135735.html
匿名

发表评论

匿名网友

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

确定