3.基于 Temporal 的 Couchbase 动态 SQL 执行场景

在使用 TemporalGo 语言 调用 Couchbase 执行 SQL 脚本时,可以通过动态参数传递到 SQL 脚本中,以下是完整实现的指南:


1. Temporal Workflow 的参数传递

Temporal 的 Workflow 支持接收动态参数,将这些参数传递给执行 SQL 的 Activity。在 Go 中可以通过结构体或键值对传递参数。


2. Couchbase N1QL 示例

Couchbase 支持通过 REST API 或 SDK 执行 N1QL 查询,并且可以使用参数化查询来防止 SQL 注入。


3. 工作流和 Activity 的结构

以下是实现动态参数化执行 Couchbase SQL 的完整示例:

Workflow 定义
go 复制代码
package workflows

import (
	"context"
	"time"

	"go.temporal.io/sdk/workflow"
)

// QueryParameters 定义 SQL 参数结构
type QueryParameters struct {
	StartTime string `json:"start_time"`
	EndTime   string `json:"end_time"`
	BrandID   int    `json:"brand_id"`
}

// Workflow 定义
func SQLWorkflow(ctx workflow.Context, params QueryParameters) error {
	ao := workflow.ActivityOptions{
		StartToCloseTimeout: time.Minute,
	}
	ctx = workflow.WithActivityOptions(ctx, ao)

	// 调用 Activity 执行 SQL
	err := workflow.ExecuteActivity(ctx, ExecuteSQLActivity, params).Get(ctx, nil)
	if err != nil {
		return err
	}

	return nil
}

Activity 定义
go 复制代码
package activities

import (
	"context"
	"encoding/json"
	"fmt"
	"log"

	"github.com/couchbase/gocb/v2" // Couchbase Go SDK
)

// QueryParameters 定义 SQL 参数结构
type QueryParameters struct {
	StartTime string `json:"start_time"`
	EndTime   string `json:"end_time"`
	BrandID   int    `json:"brand_id"`
}

// ExecuteSQLActivity 用于执行 Couchbase 的 SQL 脚本
func ExecuteSQLActivity(ctx context.Context, params QueryParameters) error {
	// 初始化 Couchbase 集群连接
	cluster, err := gocb.Connect("couchbase://localhost", gocb.ClusterOptions{
		Username: "username",
		Password: "password",
	})
	if err != nil {
		return fmt.Errorf("failed to connect to Couchbase: %w", err)
	}
	defer cluster.Close()

	// 定义 SQL 查询
	query := `
		SELECT
			pStatDate,
			brandId,
			storeId,
			SUM(incomeAmount) AS incomeAmt,
			SUM(refundAmount) AS refundAmt,
			SUM(actualAmount) AS actualAmt
		FROM ` + "`origin`.`dwd_meal_order`.`fact_batch_payment_summary`" + `
		WHERE modifyTime >= $startTime AND modifyTime < $endTime AND brandId = $brandId
		GROUP BY pStatDate, brandId, storeId
	`

	// 执行 N1QL 查询,绑定参数
	rows, err := cluster.Query(query, &gocb.QueryOptions{
		NamedParameters: map[string]interface{}{
			"startTime": params.StartTime,
			"endTime":   params.EndTime,
			"brandId":   params.BrandID,
		},
	})
	if err != nil {
		return fmt.Errorf("failed to execute query: %w", err)
	}
	defer rows.Close()

	// 解析查询结果
	for rows.Next() {
		var result map[string]interface{}
		err := rows.Row(&result)
		if err != nil {
			log.Printf("failed to read row: %v", err)
			continue
		}
		// 输出结果
		jsonResult, _ := json.Marshal(result)
		log.Printf("Result: %s", jsonResult)
	}

	if err := rows.Err(); err != nil {
		return fmt.Errorf("query execution error: %w", err)
	}

	return nil
}

启动 Workflow
go 复制代码
package main

import (
	"context"
	"log"

	"go.temporal.io/sdk/client"
	"go.temporal.io/sdk/worker"
	"your_project/activities"
	"your_project/workflows"
)

func main() {
	// 创建 Temporal 客户端
	c, err := client.Dial(client.Options{})
	if err != nil {
		log.Fatalf("unable to create Temporal client: %v", err)
	}
	defer c.Close()

	// 创建 Worker
	w := worker.New(c, "sql-task-queue", worker.Options{})
	w.RegisterWorkflow(workflows.SQLWorkflow)
	w.RegisterActivity(activities.ExecuteSQLActivity)

	// 启动 Worker
	err = w.Run(worker.InterruptCh())
	if err != nil {
		log.Fatalf("unable to start Worker: %v", err)
	}

	// 启动 Workflow
	params := workflows.QueryParameters{
		StartTime: "2024-10-01T00:00:00Z",
		EndTime:   "2024-10-31T23:59:59Z",
		BrandID:   123,
	}

	workflowOptions := client.StartWorkflowOptions{
		ID:        "sql-workflow-id",
		TaskQueue: "sql-task-queue",
	}
	we, err := c.ExecuteWorkflow(context.Background(), workflowOptions, workflows.SQLWorkflow, params)
	if err != nil {
		log.Fatalf("unable to execute Workflow: %v", err)
	}
	log.Printf("Workflow started: %s", we.GetID())
}

关键点解析

  1. 参数化 SQL 查询

    • 使用 Couchbase N1QL 的命名参数($paramName)传递动态参数。
    • 在 Activity 中通过 NamedParameters 绑定参数值。
  2. 动态 Workflow 参数传递

    • 在 Workflow 中定义参数结构(如 QueryParameters),通过 Temporal SDK 将参数传递到 Activity。
  3. Activity 执行 SQL

    • Activity 中初始化 Couchbase 连接,执行 SQL 查询,并处理返回结果。
  4. 动态配置时间范围和条件

    • StartTimeEndTime 是动态参数,Workflow 启动时通过输入指定。

运行结果

  • Temporal Workflow 启动时,动态传递参数(如时间范围 StartTimeEndTime 和条件 BrandID)。
  • Workflow 中调用 Activity 执行 SQL 查询,查询结果记录到日志中,或者返回给调用方。

这种实现方式灵活可靠,适用于基于 Temporal 的 Couchbase 动态 SQL 执行场景。

相关推荐
HackTwoHub5 小时前
AI大模型网关存在SQL注入、附 POC 复现、影响版本LiteLLM 1.81.16~1.83.7(CVE-2026-42208)
数据库·人工智能·sql·网络安全·系统安全·网络攻击模型·安全架构
l1t5 小时前
DeepSeek总结的DuckLake构建基于 SQL 原生表格式的下一代数据湖仓
数据库·sql
KmSH8umpK6 小时前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第八篇
数据库·redis·分布式
TDengine (老段)6 小时前
从施工监测到运营预警,桥科院用 TDengine 提升桥梁数据管理能力
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
S1998_1997111609•X7 小时前
论mysql国盾shell-sfa犯罪行为集团下的分项工程及反向注入原理尐深度纳米算法下的鐌檵鄐鉎行为
网络·数据库·网络协议·百度·开闭原则
KmSH8umpK8 小时前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第七篇
数据库·redis·分布式
yaodong5189 小时前
不会Python也能数据分析:Gemini 3.1 Pro解决办公问题的SQL自动生成
python·sql·数据分析
BU摆烂会噶9 小时前
【LangGraph】持久化实现的三大能力——时间旅行
数据库·人工智能·python·postgresql·langchain
l1t10 小时前
DeepSeek总结的DuckLake 入门
数据库
Joseph Cooper10 小时前
RAG 与 AI Agent:智能体真的需要检索增强生成吗?
数据库·人工智能·ai·agent·rag·上下文工程