Spanner SELECT 语句作为 Python 中的 json 数组

Spanner SELECT statement as json array in Python

我正在尝试 运行 扳手中的 select 语句,其中 returns 多行并将结果放入 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}"

我该怎么做?

您的交易似乎只是一个 select 语句。我建议使用 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))
  1. 您的 JOIN 语句有问题:

    • 每个 push_id 包含几个 message_id,因此两个表应该在 push_id 上连接,而不是 message_id
  2. MessageMessageStatus之间的潜在关系问题:

    • push_id 应该是 MessageStatus 的主键,MessageStatusMessage 的父键,检查 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 上的资源: