我需要你的帮助。 我想在一个简单的任务上测试Apache Thrift。 我在MySQL数据库中有几个表,我想将存储的数据保存到文件中。
因此,我创建了一个Thrift IDL文件,如下所示:
exception InvalidOperation {
1: i32 what,
2: string why,
}
struct Product{
1: i32 id
2: i16 resource_id,
3: i16 resource_amount,
4: double price,
5: string comment,
6: string comment_text_color,
7: string comment_bgr_color,
8: string image_file_id,
9: i16 active,
10: string title,
11: string description,
12: i16 item_index,
13: i16 is_special,
14: string banner_file_id
}
struct File{
1: string id
2: string path,
3: string checksum,
4: string size,
}
struct StaticData{
1: list<Product> Products = [];
2: list<File> Files = [];
}
service DataLibrary {
void ping(),
}
并编写了一些简单的python代码: server.py:
# -*- coding: utf-8 -*-
import thriftpy
from thriftpy.rpc import make_server
tutorial_thrift = thriftpy.load("tutorial.thrift",
module_name="tutorial_thrift")
class StaticDataHandler(object):
def __init__(self):
self.log = {}
def ping(self):
print('ping()')
def main():
server = make_server(tutorial_thrift.StaticData, StaticDataHandler(),
'127.0.0.1', 6000)
print("serving...")
server.serve()
if __name__ == '__main__':
main()
client.py:
# -*- coding: utf-8 -*-
import sys
import thriftpy
sys.path.append("gen-py")
from thriftpy.rpc import client_context
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift import Thrift
from tutorial import ttypes
tutorial_thrift = thriftpy.load("tutorial.thrift",
module_name="tutorial_thrift")
def get_products_from_db():
product_list = []
for i in range(1, 500):
product_list.append({'id': i,
'resource_id': i,
'resource_amount': i,
'price': i,
'comment': 'comment' + str(i),
'comment_text_color': 'yellow',
'comment_bgr_color': 'blue',
'image_file_id': 'file_' + str(i),
'active': 1,
'title': 'title_' + str(i),
'description': 'description' + str(i),
'item_index': i,
'is_special': 1,
'banner_file_id': 'banner_' + str(i)})
return product_list
def main():
with client_context(tutorial_thrift.DataLibrary,
'127.0.0.1', 6000) as client:
client.ping()
print("ping()")
product_list = get_products_from_db()
static_data = tutorial_thrift.StaticData()
static_data.Products.append(product_list)
static_data_save_to_file(static_data)
def static_data_save_to_file(data):
trans = TTransport.TFileObjectTransport(open("static_data", "wb"))
proto = TBinaryProtocol.TBinaryProtocol(trans)
static_data = tutorial_thrift.StaticData()
proto.writeStructBegin(static_data)
proto.writeListBegin(Thrift.TType.LIST, len(data.Products))
print(data.Products)
# proto.writeContainerList(data.Products, Thrift.TType.LIST)
proto.writeFieldEnd()
proto.writeFieldStop()
proto.writeStructEnd()
print('Recording finished')
def product_save_to_file():
trans = TTransport.TFileObjectTransport(open("data", "wb"))
proto = TBinaryProtocol.TBinaryProtocol(trans)
product_list = get_products_from_db()
product = product_list[0]
print(product)
print('Starting record data to file')
proto.writeStructBegin(product)
proto.writeFieldBegin("id", Thrift.TType.I32, 1)
proto.writeI32(product.id)
proto.writeFieldEnd()
proto.writeFieldBegin("resource_id", Thrift.TType.I16, 2)
proto.writeI16(product.resource_id)
proto.writeFieldEnd()
proto.writeFieldBegin("resource_amount", Thrift.TType.I16, 3)
proto.writeI16(product.resource_amount)
proto.writeFieldEnd()
proto.writeFieldBegin("price", Thrift.TType.DOUBLE, 4)
proto.writeDouble(product.price)
proto.writeFieldEnd()
proto.writeFieldBegin("comment", Thrift.TType.STRING, 5)
proto.writeString(product.comment)
proto.writeFieldEnd()
proto.writeFieldBegin("comment_text_color", Thrift.TType.STRING, 6)
proto.writeString(product.comment_text_color)
proto.writeFieldEnd()
proto.writeFieldBegin("comment_bgr_color", Thrift.TType.STRING, 7)
proto.writeString(product.comment_bgr_color)
proto.writeFieldEnd()
proto.writeFieldBegin("image_file_id", Thrift.TType.STRING, 8)
proto.writeString(product.image_file_id)
proto.writeFieldEnd()
proto.writeFieldBegin("active", Thrift.TType.I16, 9)
proto.writeI16(product.active)
proto.writeFieldEnd()
proto.writeFieldBegin("title", Thrift.TType.STRING, 10)
proto.writeString(product.title)
proto.writeFieldEnd()
proto.writeFieldBegin("description", Thrift.TType.STRING, 11)
proto.writeString(product.description)
proto.writeFieldEnd()
proto.writeFieldBegin("item_index", Thrift.TType.I16, 12)
proto.writeI16(product.item_index)
proto.writeFieldEnd()
proto.writeFieldBegin("is_special", Thrift.TType.I16, 13)
proto.writeI16(product.is_special)
proto.writeFieldEnd()
proto.writeFieldBegin("banner_file_id", Thrift.TType.STRING, 14)
proto.writeString(product.banner_file_id)
proto.writeFieldEnd()
proto.writeFieldStop()
proto.writeStructEnd()
print('Recording finished')
def product_read_from_file():
trans = TTransport.TFileObjectTransport(open("data", "rb"))
trans.open()
proto = TBinaryProtocol.TBinaryProtocol(trans)
ro = ttypes.Product()
ro.read(proto)
print('started')
# Display the contents of the Product
print("\nReading Product")
print("-------------------------")
print("resource_id : %d" % ro.resource_id)
print("resource_amount : %s" % ro.resource_amount)
print("Price : %f" % ro.price)
print('end')
if __name__ == '__main__':
main()
我在这行上遇到函数static_data_save_to_file:
# proto.writeContainerList(data.Products, Thrift.TType.LIST)
我无法理解,我应该向这个方法发送哪些属性,以及如何计算大小。
我试图将一个产品保存到文件并读取它,它可以工作,但现在我需要在一个结构(StaticData)中插入一些列表(产品,文件)并将其保存在文件中。
答案 0 :(得分:2)
我认为你试图以太复杂的方式做。我没有测试过以下内容,但是这样的事情应该做:
def static_data_save_to_file(data):
trans = TTransport.TFileObjectTransport(open("static_data", "wb"))
proto = TBinaryProtocol.TBinaryProtocol(trans)
data.write(proto)
print('Recording finished')
答案 1 :(得分:1)
所以,我完成了这个任务: tutorial.thrift:
exception InvalidOperation {
1: i32 what,
2: string why,
}
struct Product{
1: i32 id
2: i16 resource_id,
3: i16 resource_amount,
4: double price,
5: string comment,
6: string comment_text_color,
7: string comment_bgr_color,
8: string image_file_id,
9: i16 active,
10: string title,
11: string description,
12: i16 item_index,
13: i16 is_special,
14: string banner_file_id
}
struct File{
1: string id
2: string path,
3: string checksum,
4: string size,
}
exception InvalidValue{
1: i32 error_code,
2: string error_msg
}
struct StaticData{
1: list<Product> Products;
2: list<File> Files;
}
service DataLibrary {
}
fill_file.py:
import sys
import mysql.connector
sys.path.append('./gen-py')
from tutorial.ttypes import *
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
def get_products_from_db():
product_list = []
config = {
'user': 'user',
'password': 'qwerty',
'host': 'localhost',
'database': 'staticData',
'raise_on_warnings': True,
}
cnx = mysql.connector.connect(**config)
cursor = cnx.cursor()
query = (
"SELECT "
"id, resource_id, resource_amount, price, comment,comment_text_color,comment_bgr_color,image_file_id,active,title,description,item_index,is_special,banner_file_id "
"FROM product")
cursor.execute(query)
for (id, resource_id, resource_amount, price, comment, comment_text_color, comment_bgr_color, image_file_id, active,
title, description, item_index, is_special, banner_file_id) in cursor:
product = Product()
product.id = id
product.resource_id = resource_id
product.resource_amount = resource_amount
product.price = price
product.comment = comment
product.comment_text_color = comment_text_color
product.comment_bgr_color = comment_bgr_color
product.image_file_id = str(image_file_id)
product.active = active
product.title = title
product.description = description
product.item_index = item_index
product.is_special = is_special
product.banner_file_id = str(banner_file_id)
product_list.append(product)
cursor.close()
cnx.close()
return product_list
def static_data_save_to_file(data):
trans = TTransport.TFileObjectTransport(open("static_data", "wb"))
proto = TBinaryProtocol.TBinaryProtocol(trans)
data.write(proto)
print('Done!')
def main():
product_list = get_products_from_db()
static_data = StaticData()
static_data.Products = set(product_list)
static_data_save_to_file(static_data)
if __name__ == '__main__':
main()
read_file.py:
import sys
sys.path.append("gen-py")
from tutorial.ttypes import *
def main():
trans = TTransport.TFileObjectTransport(open("static_data", "rb"))
trans.open()
proto = TBinaryProtocol.TBinaryProtocol(trans)
ro = StaticData()
ro.read(proto)
print(ro.Products)
for product in ro.Products:
print(product)
if __name__ == '__main__':
main()