• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

gorm 和amp; postgres 使用游标获取数据

武飞扬头像
打谷机
帮助1

背景

让我们考虑这样一个场景, 你需要将数据库中一张表的数据按一定条件查询出来, 并把这些数据保存到 S3 以供以后检查使用.

问题

那么我们一般的做法是分页查询查询出来写 S3 文件.但是这里有一个问题, 那就是在查询的同时可能有新的数据写入进来, 这样会让分页失效, 导致一部分数据丢失.

解决

如果你使用 postgres, 可以用游标来解决这个问题.

package main

import (
	"fmt"
	"time"

	"github.com/davecgh/go-spew/spew"
	"gorm.io/driver/postgres"
	"gorm.io/gorm"
)

type Order struct {
	ID        int64
	OrdeID    int64
	MemberID  int64
	Price     float64
	CreatedAt time.Time
}

func (Order) TableName() string {
	return "orders"
}

func main() {

	dsn := "host=localhost user=postgres password=123456 dbname=postgres port=5432 sslmode=disable TimeZone=Asia/Shanghai"
	db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
	if err != nil {
		panic(err)
	}
    
        // 游标使用需在事务中
	tx := db.Begin()
        
        // 创建一个游标
	err = tx.Exec("DECLARE order_cursor CURSOR FOR SELECT * FROM orders order by id ASC").Error
	if err != nil {
		tx.Rollback()
		panic(err)
	}
        
        // 移动游标到开始位置
	err = tx.Exec("MOVE FORWARD 0 FROM rebate_card_cursor").Error
	if err != nil {
		tx.Rollback()
		panic(err)
	}

	for {
		var orders []*Order
                // 获取数据, 这是使用 Raw方法, 而不是 Exec
		if err := tx.Raw(fmt.Sprintf("FETCH FORWARD %d FROM rebate_card_cursor", 2)).
			Find(&orders).Error; err != nil {
			tx.Rollback()
			panic(err)
		}

		spew.Dump(orders)

		if len(orders) == 0 {
			break
		}
	}

	tx.Commit()

}

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbcabf
系列文章
更多 icon
同类精品
更多 icon
继续加载