我正在 Electron 中制作一个应用程序,并使用 Python 脚本进行查询(SQL)。 我需要将 SQL 查询的结果发送到 Electron 以在数据表中显示此数据。 我读到最好的通信方式是使用 ZMQ 库。但我不知道这是否是最好的选择。
我正在使用以下代码,如果数组(结果)很小,则该代码有效,但如果它有几行,则不会发送数组。
我正在使用以下代码,如果数组(结果)很小,则该代码有效,但如果它有几行,则不会发送该数组。 我很感激您的帮助。
应用程序.py
import zmq
from json import loads, dumps
import signal
from threading import Thread
#.......
def dataSocket():
global message
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://*:7778")
while True:
message = loads(socket.recv())
#....
if message['type']=='command':
result = querySQL() # result = [['val1','val2','val3','val4','val5','val6','val7','val8','val9','val10'],[...],[...],...,[...]]
socket.send(dumps(result).encode())
#.......
if __name__ == "__main__":
signal.signal(signal.SIGINT, signal.SIG_DFL)
Thread(target = dataSocket).start()
渲染.js
const ZMQ = require('zeromq');
const { stringify } = JSON;
const dataSock = new ZMQ.Request;
dataSock.connect("tcp://127.0.0.1:7778");
$('#sendCommand').on("click", async() => {
await dataSock.send(stringify({ type: "command", data: "" }));
[dataResponse] = await dataSock.receive();
$('#result-data').val(JSON.parse(dataResponse.toString()));
console.log(JSON.parse(dataResponse.toString()));
})
看起来您正在将 SQL 查询结果作为字符串转储到 ZMQ 消息中,并希望在 Electron 的另一端可以将其解析为 JSON。
我的建议是采用像 Google Protocol Buffers 这样的东西,序列化你想要从 Python 发送的数据,然后在 Electron (JavaScript) 中再次反序列化,并使用 ZeroMQ 来传输其间的序列化数据。这样做的目的是消除有关 Python 和 Electron / JavaScript 将如何处理/解析数据的任何歧义。它还允许您安全地拥有更复杂的数据结构;例如,如果还用于序列化您的命令,您还可以传递参数。
如果您以前没有使用过它们,您可以在 GPB .proto 文件中描述您想要发送的消息。如果您的 SQL 查询要返回二维数组,它可能看起来像这样:
message ResultLine
{
repeated int Values = 1;
}
message Results
{
repeated ResultLine Lines = 2;
}
然后使用 GPB 编译器编译该 .proto 文件,该编译器可以生成 Python 和 JavaScript 源代码。该源代码定义了类似于 Results 和 ResultLine 的类,以及将它们序列化和反序列化为 GPB 有线格式所需的所有代码。 Results 类实际上是一个二维整数数组。
因此,在 Python 中,您将为 SQL 返回中的每一行数据实例化一个新的 ResultsLine,并用该行的值填充它。然后,您可以将该 ResultsLine 添加到 Results 对象(您之前已实例化)。当你对每一行都这样做时,你会做类似的事情(这是伪代码,不是 Python)
Result = new Result
foreach row in SQLResponse
ResultLine = new ResultLine
foreach val in row
ResultLine.Values.Add(val)
Result.Lines.Add(ResultLine)
zmqMsg=new ZMQMsg(Results.SerialiseToString())
socket.send(zmqMsg)
可能有一种非常Pythonic的方式来进行迭代,并且重复值字段可能有直接摄取数组的方法(我对Python中的GPB不太熟悉)。而在另一端,
zmqMsg = socket.recv()
Results = Results.ParseFromString(zmqMsg.Content)
瞧,您现在有了一个包含您想要的数据的 Results 对象。
处理所有这些麻烦的一个非常好的事情是,您并不真正关心 ZMQ 套接字的另一端是什么。它同样可以是 C++、C#、Java、Kotlin、Go; Google Protocol Buffers 和 ZMQ 都得到了广泛的支持。你也有很大的灵活性;如果你想制作要发送的消息,只需更新 .proto 文件并重新编译,几乎所有传达额外消息字段所需的工作都已完成;您只需填充并使用它们即可。
GPB 的有线格式是二进制的,但它也有 JSON 的方言。这也很有用。