Spanner оператор SELECT в виде массива json в Python - PullRequest
0 голосов
/ 14 января 2019

Я пытаюсь запустить оператор выбора в гаечном ключе, который возвращает несколько строк и помещает этот результат в формат json.

Вот код:

def fetchmessages(self, pushid):
            rc = ResultCode.SUCCESS
            messages = ""

            def selectmessages(transaction):
                    messages = transaction.execute_update(
                    "SELECT Message.message_text FROM Message LEFT JOIN MessageStatus "
                    "ON (Message.message_id = MessageStatus.message_id) WHERE "
                    "MessageStatus.push_id = @id",
                    params={'id' : (pushid)},
                    param_types={'id' : param_types.STRING}
            )

            try:
                    self.client.run_in_transaction(selectmessages)
            except Exception as fetchexception:
                    rc = ResultCode.ERR_NO_MSG_FOUND
                    self.logger.debug(fetchexception)
                    pass

            if ResultCode.SUCCESS:
                    output = "{ 'pushid':'" + pushid + "', 'messages':" + messages + ", 'resultcode':" + str(rc.value) + "}"

            return output

Вызывающая функция просто запускает вывод через jsonify и распечатывает его. Вышеприведенный код распечатывается:

"{ 'pushid':'cdd92f4ce847efa5c7f', 'messages':, 'resultcode':1}"

Я хочу напечатать что-то вроде этого:

"{ 'pushid':'cdd92f4ce847efa5c7f', 'Messages': [{'message': 'foo bar'}, { 'message': 'core dump'}], 'resultcode': 1}"

Как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 21 января 2019
  1. В вашем утверждении JOIN есть проблема:

    • каждая push_id содержит несколько message_id, поэтому обе таблицы должны объединяться в push_id, а не message_id
  2. Потенциальная проблема взаимосвязи между таблицами Message и MessageStatus:

    • push_id должен быть первичным ключом MessageStatus, а MessageStatus родительским Message, проверьте, правильно ли задан DDL в этом примере:

DDL:

CREATE TABLE MessageStatus (
push_id string(50) NOT NULL
) PRIMARY KEY (push_id);


CREATE TABLE Message (
push_id string(50), NOT NULL,
message_id string(50) NOT NULL,
message_text string(50)
) PRIMARY KEY (push_id, message_id),
INTERLEAVE IN PARENT MessageStatus ON DELETE CASCADE;

Сценарий запроса:

from google.cloud import spanner

def fetch_messages(instance_id, database_id):
    spanner_client = spanner.Client()
    instance = spanner_client.instance(instance_id)
    database = instance.database(database_id)

    with database.snapshot() as snapshot:
        results = snapshot.execute_sql(
            'SELECT Message.push_id, Message.message_id, Message.message_text FROM Message LEFT JOIN MessageStatus '
            'ON MessageStatus.push_id = Message.push_id WHERE MessageStatus.push_id="JDHK65FTRD832KJ"')
        for row in results:
            print(u'push_id: {}, message_id: {}, message_text: {}'.format(*row))


fetch_messages([INSTANCE_ID], [DATABASE_ID])

Результат:

push_id: JDHK65FTRD832KJ, message_id: 1, message_text: First
push_id: JDHK65FTRD832KJ, message_id: 2, message_text: Second
push_id: JDHK65FTRD832KJ, message_id: 3, message_text: Third

Ресурсы на GCP:

0 голосов
/ 14 января 2019

Похоже, что ваша транзакция является только оператором выбора. Я рекомендую использовать метод execute_sql, как показано ниже:

spanner_client = spanner.Client()
instance = spanner_client.instance(instance_id)
database = instance.database(database_id)

with database.snapshot() as snapshot:
    results = snapshot.execute_sql(
        "SELECT Message.message_text FROM Message LEFT JOIN MessageStatus "
        "ON (Message.message_id = MessageStatus.message_id) WHERE "
        "MessageStatus.push_id = @id",
        params={'id' : (pushid)},
        param_types={'id' : param_types.STRING})

    for row in results:
        print(u'Message: {}'.format(*row))
...