Как получить отфильтрованные данные из Bigtable с помощью Python? - PullRequest
1 голос
/ 22 апреля 2019

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

Таблица выглядит следующим образом:

arc_record_id | record_id | batch_id
1             |624        |86
2             |625        |86
3             |626        |86 

и так далее ... до arc_record_id 10.

Я попробовал это, приведенный ниже код Python:

visit_dt_filter = ValueRangeFilter(start_value = "1".encode('utf-8'), 
end_value = "2".encode('utf-8'))

col1_filter = ColumnQualifierRegexFilter(b'arc_record_id')

chain1 = RowFilterChain(filters=[col1_filter, visit_dt_filter])

partial_rows = testTable.read_rows(filter_=chain1)

for row in partial_rows:
    cell = row.cells[columnFamilyid1]["arc_record_id".encode('utf-8')][0]
    print(cell.value.decode('utf-8'))

Rowkey -

prim_key=row_value[0] //which is arc_record_id 
row_key="RecordArchive{}".format(prim_key).encode('utf-8') 

Я получаю вывод как

1
10
2
3

Я ожидаю, что результат будет

arc_record_id | record_id | batch_id
1             |624        |86
2             |625        |86

1 Ответ

2 голосов
/ 23 апреля 2019

Есть несколько проблем с вашим кодом, которые помогут вам получить то, что вы хотите:

  1. Bigtable использует лексикографическая сортировка по произвольным байтам , поэтому порядок сортировки1, 10, 2, 3 и так далее.Вот почему 10 включается в ваш набор результатов.Это можно исправить, добавив слева свои числа, чтобы они сохранялись как 000000001, 000000002. (Вы можете уменьшить неэффективность этого, храня в шестнадцатеричном или даже двоичном виде). ​​

  2. Поскольку вы толькоprint row.cells[columnFamilyid1]["arc_record_id".encode('utf-8')] вы выводите только arc_record_id.

  3. Поскольку столбец, который вы хотите отфильтровать, является ключом строки, проще и эффективнее напрямую указать read_rows диапазон для чтения:read_rows(start_key="RecordArchive1".encode('utf-8'), end_key="RecordArchive3".encode('utf-8'))

В общем, попробуйте код вроде:

KEY_PREFIX = "RecordArchive".encode('utf-8')
ARC_RECORD_ID_COL = "arc_record_id".encode('utf-8')
RECORD_ID_COL = "record_id".encode('utf-8')
BATCH_ID_COL = "batch_id".encode('utf-8')

# Functions used to store/retrieve integer values. Supports IDs up to 2**31
def pack_int(i):
    return struct.pack('>l', i)
def unpack_int(b):
    return struct.unpack('>l', b)[0]
# row key of a record of given arc_record_id
def rowkey(id):
    return KEY_PREFIX + pack_int(id)

results = table.read_rows(start_key=rowkey(1), end_key=rowkey(2), end_inclusive=True)
print("arc_record_id,record_id,batch_id")
for row in results:
    print("{},{},{}".format(
              unpack_int(row.cell[columnFamilyid1][ARC_RECORD_ID_COL][0].value),
              unpack_int(row.cell[columnFamilyid1][RECORD_ID_COL][0].value),
              unpack_int(row.cell[columnFamilyid1][BATCH_ID_COL][0].value)))
...