Как сделать транзакции.insert_or_update для вторичного индекса, а не первичного индекса? - PullRequest
0 голосов
/ 21 ноября 2019

У меня есть таблица в 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)

И я пытаюсь выполнить transaction.insert_or_update через скрипт на python. Для каждой строки в фрейме данных pandas я делаю:

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"] уже присутствовала в KeyColumn таблицы, обновите ее parent_idв противном случае вставьте новую строку в таблицу Spanner, соответствующую этому KeyColumn. Но так как мой первичный ключ - Id, который генерируется случайным образом uuid.uuid4().hex, он каждый раз вставляет новую строку.

Ответы [ 2 ]

0 голосов
/ 21 ноября 2019

Здесь есть способ запросить облачный гаечный ключ с определенным индексом. Вы должны использовать что-то вроде этого в конце вашего запроса: FROM test_id@{FORCE_INDEX=KeyColumnIndex}.

Несмотря на то, что это способ выполнения запросов по вторичным индексам и ответ на вопрос в заголовке, я не знаю, какнасколько это может быть применено в вашем случае использования.

0 голосов
/ 21 ноября 2019

Если я правильно вас понимаю, следующая ситуация:

  • ID - это первичный ключ вашей таблицы.
  • Для таблицы определен уникальный индексв столбце KeyColumn.
  • Вы хотите insert_or_update строку, используя KeyColumn в качестве столбца, который следует использовать, чтобы определить, существует ли строка.

Ток сожалению не возможно. insert_or_update всегда будет использовать первичный ключ таблицы, чтобы определить, существует ли строка. Я могу придумать три возможных решения этой проблемы, но все они имеют свои недостатки:

  • Вы можете изменить определение таблицы и сделать KeyColumn первичным ключом и установить уникальный индекс для Id столбец. Проблема в этом, конечно, в том, что любой другой код, который зависит от Id как первичного ключа, также должен быть изменен. Это также довольно громоздкое изменение, поскольку Cloud Spanner не позволяет вам изменять первичный ключ таблицы, поэтому вам придется создать копию таблицы test_id и затем удалить старую таблицу.
  • Вы можете получить строку из Cloud Spanner перед обновлением, прочитав ее, используя имеющееся у вас значение KeyColumn. Большая проблема с этим, очевидно, производительность. Вам нужно будет выполнить чтение для каждой строки, которую вы хотите обновить.
  • Вы можете использовать инструкцию DML (UPDATE test_id SET parent_id=@parent WHERE KeyColumn=@key), чтобы выполнить обновление и проверить, действительно ли оно обновило строку, проверив возвращенное обновлениесосчитать. Если он ничего не обновил, вы можете выполнить вставку. Очевидно, это также будет медленнее, чем мутация insert_or_update.
...