doushih06137 2018-09-27 11:19
浏览 109

使用Golang和Gocqlx在Cassandra中进行多分区批处理

I'm trying to perform a multiple-partition BATCH in Cassandra using Golang and Gocqlx.

My problem is that I can't get my BATCH statements to work properly.

My goal is as follows:

1. Perform an INSERT to second_table.
2. Perform an UPDATE to first_table.
3. Batch the above 2 operations because they need to be all-or-nothing.

I have the following table structure in Cassandra:

keyspace: mykeyspace

first_table:
    uuid
    second_table_uuid  <-- serves as a link to second_table
    create_timestamp
    update_timestamp

second_table:
    uuid
    first_table_uuid   <-- serves as a link to first_table
    create_timestamp
    update_timestamp

Below is my code:

func InsertToSecondTable(payload payload.SecondTable, session *gocql.Session) (string, error) {
    // Make sure payload UUID exists on `first_table`.
    firstTableSelectStmt, firstTableSelectNames := qb.Select("mykeyspace.first_table").
        Where(qb.Eq("uuid")).
        ToCql()

    var firstTableRow table.FirstTable

    q := gocqlx.Query(session.Query(firstTableSelectStmt), firstTableSelectNames).BindMap(qb.M{
        "uuid": payload.UUID,
    })

    // Will return a `not found` error if no matches are found.
    if err := q.GetRelease(&firstTableRow); err != nil {
        return "", err
    }

    // Prepare INSERT to `second_table` query
    now := time.Now()

    uuid, _ := gocql.RandomUUID()   

    var secondTableRow table.SecondTable
    secondTableRow.UUID = uuid
    secondTableRow.CreateTimestamp = now
    secondTableRow.UpdateTimestamp = now

    // Handle UUIDs.
    secondTableRow.FirstTableUUID, _ = getUUIDFromString(payload.UUID)

    secondTableInsertStmt, secondTableInsertNames := qb.Insert("mykeyspace.second_table").
        Columns("uuid", "first_table_uuid", "create_timestamp", "update_timestamp").
        ToCql()

    // Prepare UPDATE on `first_table` query.
    firstTableUpdateStmt, firstTableUpdateNames := qb.Update("mykeyspace.first_table").
        Set("second_table_uuid", "update_timestamp").
        Where(qb.Eq("uuid")).
        ToCql()

    // Start a Batch.
    // This is because we want the INSERT and UPDATE to be all-or-nothing.
    finalStmt, finalNames := qb.Batch().AddStmt(secondTableInsertStmt, secondTableInsertNames).
        AddStmt(firstTableUpdateStmt, firstTableUpdateNames).
        ToCql()

    // Had to change the anonymous struct field names so they don't conflict.
    // Use DB tags to match the INSERT and UPDATE statements.
    batchStruct := struct {
        // second_table
        SecondTableUUIDPK          gocql.UUID `db:"uuid"`
        FirstTableUUID             gocql.UUID `db:"first_table_uuid"`       
        SecondTableCreateTimestamp time.Time  `db:"create_timestamp"`
        SecondTableUpdateTimestamp time.Time  `db:"update_timestamp"`
        // first_table
        FirstTableUUIDPK    gocql.UUID `db:"uuid"`  
        SecondTableUUID     gocql.UUID `db:"second_table_uuid"`
        FirstTableTimestamp time.Time  `db:"create_timestamp"`
        FirstTableTimestamp time.Time  `db:"update_timestamp"`
    }{
        // second_table
        SecondTableUUIDPK:          secondTableRow.UUID,
        FirstTableUUID:             secondTableRow.FirstTableUUID,      
        SecondTableCreateTimestamp: secondTableRow.CreateTimestamp,
        SecondTableUpdateTimestamp: secondTableRow.UpdateTimestamp,
        // first_table
        MainUUIDPK:          firstTableRow.UUID,        
        AdditionalDataUUID:  firstTableRow.SecondTableUUID,
        MainCreateTimestamp: firstTableRow.CreateTimestamp,
        MainUpdateTimestamp: firstTableRow.UpdateTimestamp,
    }

    err = gocqlx.Query(session.Query(finalStmt), finalNames).
        BindStruct(&batchStruct).
        ExecRelease()
    if err != nil {
        return "", err
    }

    return uuid.String(), nil
}

It's probably something super obvious, but I'm sadly new to Cassandra and Gocqlx.

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
    • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
    • ¥15 如何在炒股软件中,爬到我想看的日k线
    • ¥15 seatunnel 怎么配置Elasticsearch
    • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
    • ¥15 (标签-MATLAB|关键词-多址)
    • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
    • ¥500 52810做蓝牙接受端
    • ¥15 基于PLC的三轴机械手程序
    • ¥15 多址通信方式的抗噪声性能和系统容量对比