如何在二级索引而非主索引上进行transaction.insert_or_update?

我在Google Cloud Spanner中有一张桌子。

CREATE TABLE test_id (
    Id STRING(MAX) NOT NULL,KeyColumn STRING(MAX) NOT NULL,parent_id INT64 NOT NULL,Updated TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true),) PRIMARY KEY (Id)

而且,我正在尝试通过python脚本执行transaction.insert_or_update。 对于熊猫数据框中的每一行,我正在做:

transaction.insert_or_update(
                'test_id',columns=['Id','KeyColumn','parent_id','Updated'],values=[(uuid.uuid4().hex,row["KeyColumn"],row["parent_id"],spanner.COMMIT_TIMESTAMP)],)

我想要的是,如果表的KeyColumn中已经存在row [“ KeyColumn”],请更新其parent_id列,否则在Spanner表中插入与之对应的新行KeyColumn。 但是由于我的主键是Id,它是由uuid.uuid4().hex随机生成的,因此每次插入新行。

wwchwoeoprpr 回答:如何在二级索引而非主索引上进行transaction.insert_or_update?

如果我对您的理解正确,则情况如下:

  • ID是表的主键。
  • 在列KeyColumn上为表定义了唯一索引。
  • 您要使用insert_or_update作为要用于确定该行是否已存在的列的KeyColumn行。

很遗憾,这是不可能的。 insert_or_update将始终使用表的主键来确定该行是否存在。我可以想到三种解决此问题的方法,但是它们都有缺点:

  • 您可以更改表定义并将KeyColumn用作主键,并在Id列上设置唯一索引。当然,与此有关的问题是,依赖Id作为主键的任何其他代码也都需要更改。这也是一个相当麻烦的更改,因为Cloud Spanner不允许您更改表的主键,因此您必须创建test_id表的副本,然后删除旧表。
  • 您可以通过使用拥有的KeyColumn值读取行来从Cloud Spanner获取行,然后进行更新。最大的问题显然是性能。您需要对要更新的每一行进行读取。
  • 您可以使用DML语句(UPDATE test_id SET parent_id=@parent WHERE KeyColumn=@key)执行更新,并通过检查返回的更新计数来检查它是否实际上更新了一行。如果它没有更新任何内容,则可以执行插入。这显然也比insert_or_update突变要慢。
,

Here提供了一种使用特定索引查询Cloud Spanner的方法。 您应该在查询的结尾使用类似以下的内容:FROM test_id@{FORCE_INDEX=KeyColumnIndex}

即使这是在二级索引上执行查询以及标题中问题的答案的方式,我也不知道在您的用例中可以应用多少。

本文链接:https://www.f2er.com/3060805.html

大家都在问