【发布时间】:2017-04-29 14:05:35
【问题描述】:
我有一个 MySQL 数据库,其中包含 6 个表和大约 200 万行。
我想将所有数据迁移到 MongoDB。
我决定通过将 SQL 表转换为 JSON 并将其导入 MongoDB 来做到这一点。
我用 Golang 编写了一个程序来提取数据并将其输出为 JSON。
这是程序的主要功能:
func main() {
// Open a database connection
var err error
db, err = sql.Open("mysql", "root:password@tcp(127.0.0.1:3306)/employees")
checkErr(err)
// Check if reachable
if err = db.Ping(); err != nil {
log.Fatal("Database is unreachable:", err)
}
// Populate variables with data
err = populateVars()
checkErr(err)
// Marshal variables into JSON
binaryJSON, err := json.Marshal(collection)
checkErr(err)
// Write JSON to a file
err = writeStringToFile("/home/user01/Temporary/sql2data.json", string(binaryJSON))
checkErr(err)
}
问题是输出不一致。
每次我运行程序时,生成的文件都有不同的大小,并且缺少一些随机字段。
这可能是什么原因造成的?
这似乎不是程序逻辑的问题,因为一切都执行没有错误,并且大多数字段都填充得很好。
会不会是我阅读信息太快,以至于偶尔会丢失一些东西?
或者我还有什么遗漏的吗?
编辑:
大部分工作发生在populateVars() 函数调用中。
它有多个代码块来执行给定的 SQL 查询并根据架构填充结构变量。
这是一个这样的块:
rows, err = db.Query("SELECT emp_no, dept_emp.dept_no, dept_name, from_date, to_date FROM dept_emp JOIN departments ON departments.dept_no = dept_emp.dept_no;")
checkErr(err)
i := 0
for rows.Next() {
var id int
var depNumber string
var depName string
var fromDate string
var toDate string
var position = "Employee"
err = rows.Scan(&id, &depNumber, &depName, &fromDate, &toDate,)
// For debugging purposes:
fmt.Println(id, depNumber, depName, fromDate, toDate, position, i)
if err != nil {
return err
}
for i := range collection {
if collection[i].ID == id {
collection[i].Departments = append(collection[i].Departments, Department{DepartmentNumber: depNumber, DepartmentName: depName, FromDate: fromDate, ToDate: toDate, Position: position})
// For debugging purposes:
fmt.Println(collection[i].Departments)
}
}
i++
}
这是整个程序的 GitHub 链接: https://github.com/dchmie01/mysql_to_json/blob/master/main.go
编辑 2:
问题似乎与查询超时有关。
每个查询执行大约需要 10 分钟,但在大约 6 分钟后,我收到此错误,程序停止执行查询:
[mysql] 2017/04/29 17:35:16 packets.go:66: unexpected EOF
[mysql] 2017/04/29 17:35:16 packets.go:412: busy buffer
2017/04/29 17:35:16 driver: bad connection
在 MySQL 日志文件中它说:
2017-04-29T16:28:49.975805Z 102 [Note] Aborted connection 102 to db: 'employees' user: 'root' host: 'localhost' (Got timeout writing communication packets)
到目前为止,我尝试使用 MySQL 变量来禁用任何可能存在的超时,但没有运气。
我认为问题可能出在 Go 的 mysql 驱动程序上。
【问题讨论】:
-
您知道您可以使用 CSV:Mysql SELECT INTO OUTFILE 和 mongoiport --type csv。
-
不容易,我需要重构架构,而不是转储所有的表。
-
我通常为此使用聚合,如果你做一些非常复杂的事情,我认为不一致可能来自那里。问题中的代码不足以就该部分给出任何答案。
-
谢谢,我添加了更长的解释。在读取每一行时,我主要只是将结构变量附加到结构切片。
-
collection的大小和查询返回的rows的个数一样吗?也就是说,您是否将集合预分配给已知数量的返回行?并且所有查询(用于填充相同collection切片的结果)是否返回相同数量的行?