Jenkins教程-10-发送飞书测试报告通知
上一小节我们学习了发送企业微信测试报告通知的方法,本小节我们讲解一下发送飞书测试报告通知的方法。
1、自动化用例执行完后,使用pytest_terminal_summary钩子函数收集测试结果,存入本地status.txt文件中,供Jenkins调用
conftest.py代码如下:
#conftest.py def pytest_terminal_summary(terminalreporter, exitstatus, config):"""收集测试报告summary,并存入status.txt文件中,供Jenkins调用"""print("pytest_terminal_summary")passed_num = len([i for i in terminalreporter.stats.get('passed', []) if i.when != 'teardown'])failed_num = len([i for i in terminalreporter.stats.get('failed', []) if i.when != 'teardown'])error_num = len([i for i in terminalreporter.stats.get('error', []) if i.when != 'teardown'])skipped_num = len([i for i in terminalreporter.stats.get('skipped', []) if i.when != 'teardown'])total_num = passed_num + failed_num + error_num + skipped_numtest_result = '测试通过' if total_num == passed_num + skipped_num else '测试失败'duration = round((time.time() - terminalreporter._sessionstarttime), 2)# 定义目录路径directory_path = './reports/'# 确保文件所在的目录存在os.makedirs(os.path.dirname(directory_path), exist_ok=True)# 定义文件路径file_path = os.path.join(directory_path, 'status.txt')with open(file_path, 'w', encoding='utf-8') as f:f.write(f'TEST_TOTAL={total_num}\n')f.write(f'TEST_PASSED={passed_num}\n')f.write(f'TEST_FAILED={failed_num}\n')f.write(f'TEST_ERROR={error_num}\n')f.write(f'TEST_SKIPPED={skipped_num}\n')f.write(f'TEST_DURATION={duration}\n')f.write(f'TEST_RESULT={test_result}\n')
本地文件status.txt中收集测试结果示例:
2、Jenkins中安装Environment Injector 和description setter 插件
Environment Injector插件用于注入环境变量
自动化测试任务配置中,添加构建步骤
填写测试结果收集文件status.txt的路径
description setter用于构建后设置任务描述
将status.txt中的的测试结果字段映射到任务描述中
执行任务构建后,任务描述中会显示构建的测试结果,如下
3、安装python-jenkins 库,读取自动化测试任务构建后的测试结果描述信息
pip install python-jenkins
代码如下
# qywechat_remind.py
import json
from datetime import datetime
import jenkins
import requests
import jmespathhost = "http://localhost:8080/"
username = 'admin'
password = 'xxxxxxxxxx'
webhook = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=f4444444444-c1d3-47f2-be78-098f80c2d194"
env = "test"
stage = "回归测试"
job = "auto_api_test"
maintainer = "米兔1号"
server = jenkins.Jenkins(host, username=username, password=password)
last_build_number = server.get_job_info(job)['lastCompletedBuild']['number']
build_info = server.get_build_info(job, last_build_number)
console_url = build_info['url'] + "console"
report_url = build_info['url'] + 'allure'
# report_url = ip_host + report_url.split(":")[-1]
test_status = json.loads(build_info['description'])
print("构建测试结果描述信息:", test_status)total = test_status["total"]
passed = test_status["passed"]
passed_ratio = round(passed / total, 4) * 100
failed = test_status["failed"]
failed_ratio = round((100 - passed_ratio), 2)
error = test_status["error"]
skipped = test_status["skipped"]
duration = test_status["duration"]
build_time = datetime.fromtimestamp(build_info['timestamp'] / 1000).strftime('%Y-%m-%d %H:%M:%S')
success = total == (passed + skipped) if passed != 0 else False
执行上述代码,可以看出,已经获取到jenkins任务的测试结果信息了
4、上一步获取到的测试结果信息,包装成消息体,调用飞书机器人发送群消息接口,自动发送消息到群里
飞书机器人的配置和接口,请参考:开发文档 - 飞书开放平台
飞书发送测试结果消息的整体代码如下:
import json
from datetime import datetime
import jenkins
import requests
import jmespathhost = "http://localhost:8080/"
username = 'admin'
password = 'xxxxx'
webhook = "https://open.feishu.cn/open-apis/bot/v2/hook/c82222qqw64de8a-cac3-4523-b234-85269cf4945d"
env = "test"
stage = "回归测试"
job = "auto_api_test"
maintainer = "米兔1号"
server = jenkins.Jenkins(host, username=username, password=password)
last_build_number = server.get_job_info(job)['lastCompletedBuild']['number']
build_info = server.get_build_info(job, last_build_number)
print("构建信息:", build_info)
console_url = build_info['url'] + "console"
print("console:", console_url)
report_url = build_info['url'] + 'allure'
print("report_url:", report_url)
test_status = json.loads(build_info['description'])
print("测试结果:", test_status)
total = test_status["total"]
passed = test_status["passed"]
passed_ratio = round(passed / total, 4) * 100
print("passed_ratio", passed_ratio)
failed = test_status["failed"]
failed_ratio = round((100 - passed_ratio), 2)
print("failed:", failed_ratio)
error = test_status["error"]
skipped = test_status["skipped"]
duration = test_status["duration"]
build_time = datetime.fromtimestamp(build_info['timestamp'] / 1000).strftime('%Y-%m-%d %H:%M:%S')
success = total == (passed + skipped) if passed != 0 else False
# 使用Jenkins API token 模拟登录
USERNAME = "admin"
# Jenkins API token
TOKEN = "113b81ae7fd66046859f1b9833d391621a"
url_suites = f"{report_url}/data/suites.json"
# print("url_suites", url_suites)
res = requests.get(url_suites, auth=(USERNAME, TOKEN))
# print("res", res.content)
s_url = f"{report_url}/#suites/"
# print('s_url', s_url)
url_raw_list = jmespath.search("children[].children[].children[].children[?status=='failed'||status=='broken'].{name:name,parentUid:parentUid,uid:uid,status:status,tags:tags}",res.json())
# print("url_raw_list", url_raw_list)url_list = []
for raw in url_raw_list[0]:url_dict = {"name": raw["name"], "url": s_url + raw["parentUid"] + "/" + raw["uid"] + "/", "uid": raw["uid"],"status": raw["status"], "author": raw["tags"][0]}url_list.append(url_dict)
# print("url_list", url_list)url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal"payload = json.dumps({"app_id": "cli_asss6baddbc63b4500c","app_secret": "c39BsssskuRpZqbXzgcyab7fqgRVkTfT7skL"
})
headers = {'Content-Type': 'application/json'
}response = requests.request("POST", url, headers=headers, data=payload).json()
# red = "#FF0000"
# green = "#00ff00"
a = 'green'
b = 'red'
c = 'yellow'
card_demo = {"msg_type": "interactive","card": {"elements": [{"tag": "div","text": {"content": f"-**任务名称**:{job}\n\n-**测试阶段**:{stage}\n\n-**测试结果**:<font color={a if success else b}>{'通过~' if success else '失败!'}</font> {chr(0x1f600) if success else chr(0x1f627)}\n\n-**用例总数**:{total}\n\n-**通过数**:<font color={a}>{passed}</font>\n\n-**通过率**:{passed_ratio}%\n\n-**失败数**:<font color={b}>{failed}</font>\n\n-**失败率**:{failed_ratio}%\n\n-**错误数**:{error}\n\n-**跳过数**:{skipped}\n\n-**执行人**:@{maintainer}\n\n-**执行时间**:{build_time}\n\n-**执行耗时**:{duration}s\n\n","tag": "lark_md"}}, {"actions": [{"tag": "button","text": {"content": "查看测试报告","tag": "lark_md"},"url": report_url,"type": "primary","value": {"key": "value"}}],"tag": "action"}],"header": {"template": "wathet","title": {"content": "钉钉oapi接口测试任务执行报告通知","tag": "plain_text"}}}
}# payload = json.dumps({
# "msg_type": "post",
# "content": {
# "post": {
# "zh_cn": {
# "title": "钉钉oapi接口测试报告",
# "content": [
# [
# {
# "tag": "text",
# "text": f"【用例总数】:{total} \n"
# },
# {
# "tag": "text",
# "text": f"【测试通过】:{passed} \n"
# },
# {
# "tag": "text",
# "text": f"【测试失败】:{failed} \n"
# },
# {
# "tag": "text",
# "text": f"【测试错误】:{error} \n"
# },
# {
# "tag": "text",
# "text": f"【测试跳过】:{skipped} \n"
# },
# {
# "tag": "text",
# "text": f"【测试耗时】:{duration}s \n"
# },
# {
# "tag": "text",
# "text": f"【测试时间】:{build_time} \n"
# },
# {
# "tag": "text",
# "text": f"【测试结果】: {'通过~' if success else '失败!'}{chr(0x1f600) if success else chr(0x1f627)} \n"
# },
# {
# "tag": "a",
# "text": "Allure详细报告,请查看",
# "href": f"{report_url}"
# }
# ]
# ]
# }
# }
# }
# })
payload = json.dumps(card_demo)headers = {'Authorization': f"Bearer {response['tenant_access_token']}",'Content-Type': 'application/json'
}requests.request("POST", webhook, headers=headers, data=payload)# 单个报告,详细数据
# http://localhost:8080/job/auto_api_test/76/allure/data/test-cases/9a4eba68509440c8.jsonphone_mapping = {"zhang.san": "13421503860","li.si": "14564591649"
}
single_url = f"{report_url}/data/test-cases/"
for case in url_list:url = single_url + str(case["uid"]) + ".json"res = requests.get(url, auth=(USERNAME, TOKEN)).json()case["message"] = res["statusMessage"]
print("url_list", url_list)
author_list = list(set(jmespath.search("[*].author", url_list)))
# print("author_list",author_list)
failed_list = jmespath.search("[?status=='failed']", url_list)
print("failed_list", failed_list)
broken_list = jmespath.search("[?status=='broken']", url_list)
print("broken_list", broken_list)phone_list = []failed_string = f"<font color={b}>【**失败用例**】:\n</font>"
broken_string = f"<font color={c}>【**错误用例**】:\n</font>"for url_info in url_list:name_text = " " + url_info["name"] + "\n"url_text = "[" + " " + url_info["message"] + "]" + "(" + url_info["url"] + ")" + "\n"single_case_text = name_text + url_text# at_dict = {# "tag": "at",# "user_id": 1111,# }if url_info["status"] == "failed":failed_string += single_case_text# failed_string_list.append(url_dict)# failed_string_list.append(at_dict)elif url_info["status"] == "broken":failed_string += single_case_text# broken_string_list.append(name_dict)# broken_string_list.append(url_dict)# broken_string_list.append(at_dict)
null_string = " " + f"无\n"
if not failed_list:failed_string += null_string
if not broken_list:broken_string += null_string
# print("failed_string_list", failed_string_list, type(failed_string_list))
# print("broken_string_list", broken_string_list, type(broken_string_list))
# end_string_list = [{
# "tag": "a",
# "text": "Allure详细报告,请查看",
# "href": f"{report_url}"
# }]
all_string = failed_string + broken_string
# print("all_string", all_string_list, type(all_string_list))data_ca_demo = {"msg_type": "interactive","card": {"elements": [{"tag": "div","text": {"content": all_string,"tag": "lark_md"}}, {"actions": [{"tag": "button","text": {"content": "查看测试报告","tag": "lark_md"},"url": report_url,"type": "primary","value": {"key": "value"}}],"tag": "action"}],"header": {"template": "wathet","title": {"content": "钉钉oapi接口测试任务执行错误日志通知","tag": "plain_text"}}}
}
# data_ca = {
# "msg_type": "post",
# "content": {
# "post": {
# "zh_cn": {
# "title": "钉钉oapi接口测试报错信息汇总",
# "content": all_string_list
# }
# }
# }
# }
print("data_ca", data_ca_demo)
for author in author_list:if author in list(phone_mapping.keys()):phone_list.append(phone_mapping[author])
print(phone_list)response_r = requests.request("POST", webhook, headers=headers, data=json.dumps(data_ca_demo))
print("response_r", response_r.json())
4、执行上述脚本,查看飞书通知,如下
测试结果信息:
错误日志信息:
最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走,希望可以帮助到大家!
相关文章:
Jenkins教程-10-发送飞书测试报告通知
上一小节我们学习了发送企业微信测试报告通知的方法,本小节我们讲解一下发送飞书测试报告通知的方法。 1、自动化用例执行完后,使用pytest_terminal_summary钩子函数收集测试结果,存入本地status.txt文件中,供Jenkins调用 conft…...
Swift开发——简单App设计
App的界面设计需要具有大量的图像并花费大量的时间,这样的应用不方便学习和交流,这里重点介绍SwiftUI界面元素的用法,通过简单App设计过程的讲解,展示图形用户界面应用程序的设计方法。 01、简单App设计 按照9.1节工程MyCh0901的创建方法,创建一个新的工程MyCh0902,此时工…...
Python操作mysql
一、python连接mysql 1.python连接mysql代码示例 from pymysql import Connection# 获取到mysql数据艰苦的连接对象 conn Connection(hostlocalhost,port3306,userroot,passwordroot ) # 打印mysql数据库软件信息 print(conn.get_server_info()) # 关闭到数据库的连接 conn.…...
监控易产品升级动态:V7.6.6.15版本全面升级
随着信息技术的不断发展,企业对系统监控和数据管理的需求日益增加。为了满足广大用户的实际需求,监控易团队经过不懈努力,成功推出了V7.6.6.15版本,对产品进行了全面升级和优化。本次升级不仅增强了产品的稳定性和可靠性ÿ…...
Vue3 + Element-plus + TS —— 动态表格自由编辑
前期回顾 《 穿越时空的代码、在回首:Evil.js两年后的全新解读 》-CSDN博客 Vue3 TS Element-Plus 封装Tree组件 《亲测可用》_ https://blog.csdn.net/m0_57904695/article/details/131664157?spm1001.2014.3001.5501 态表格 自由编辑 目录 ♻️ 效果图…...
虚拟机配置桥接模式
背景 因为要打一些awd比赛,一些扫描工具什么的,要用到kali,就想着换成一个桥接模式 但是我看网上的一些文章任然没弄好,遇到了一些问题 前置小问题 每次点开虚拟网络编辑器的时候都没有vmnet0,但是点击更改的时候却有vmnet0 第一步: 点击更改设置 第二步: 把wmnet0删掉 …...
星戈瑞DSPE-SS-PEG-CY7近红外花菁染料
DSPE-SS-PEG-CY7是一种具有复杂而精细结构的复合纳米材料,其在生物医学领域的应用增多。该材料结合了磷脂(DSPE)、聚乙二醇(PEG)、二硫键(SS)以及荧光染料(CY7)的特点&am…...
LeetCode:503. 下一个更大元素 II(Java 单调栈)
目录 503. 下一个更大元素 II 题目描述: 实现代码与解析: 单调栈 原理思路: 503. 下一个更大元素 II 题目描述: 给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] )&…...
代码重构:解读重构概念及重构实战
目录 一.重构是什么(what) 1.重构的本质 2.重构≠性能优化 二.重构的目的(why) 1.去写好的代码 2.去写更灵活的代码 三.重构的时机(when and where) 1.何时重构 2.何时不重构 四.重构的方法(how) 1.重构关键核心 2.重构方法 3.重构工具 小结 一.重构是什么(what)…...
java.util.Optional类介绍
java.util.Optional 是 Java 8 引入的一个容器类,用于表示可能包含或不包含非空值的对象。它的设计初衷是为了减少程序中的空指针异常(NullPointerException),并使代码更加简洁和易读。 Optional 类的介绍 1. 特点 避免显式的 null 检查:使用 Optional 可以避免显式的 n…...
PhotoShop自动生成号码牌文件
1、说明 设计卡牌的时候,遇到自动生成编号,从01500到-02500,一个一个的手写,在存储保存成psd格式的文件,会很耗时。 下面将介绍如何使用ps自动生成psd格式的文件 2、使用excle生成数字 从01500到-02500 第一步&…...
02逻辑代数与硬件描述语言基础
2.1 逻辑代数(简单逻辑的运算) 2.2 逻辑函数的卡诺图(从图论的角度)化简法 2.3 硬件描述语言Verilog HDL基础(研究生阶段才用得到) 要求: 1、熟悉逻辑代数常用基本定律、恒等式和规则。 2、掌握…...
OpenGL3.3_C++_Windows(21)
抗锯齿 遇到模型边缘有锯齿:光栅器将顶点数据转化为片段的方式有关 抗锯齿:产生更平滑的边缘SSAA超采样抗锯齿:使用比正常分辨率更高的分辨率,来渲染场景,它也会带来很大的性能开销。 光栅器: 位于最终处…...
clickhouse学习
ClickHouse学习 安装部署 1.下载rpm文件 下载地址:https://packages.clickhouse.com/rpm/stable/ clickhouse-client-23.2.1.2537.x86_64.rpm clickhouse-common-static-23.2.1.2537.x86_64.rpm clickhouse-common-static-dbg-23.2.1.2537.x86_64.rpm clickhous…...
MySQL高级-索引-使用规则-前缀索引
文章目录 1、前缀索引2、前缀长度3、查询表数据4、查询表的记录总数5、计算并返回具有电子邮件地址(email)的用户的数量6、从tb_user表中计算并返回具有不同电子邮件地址的用户的数量7、计算唯一电子邮件地址(email)的比例相对于表…...
外星生命在地球的潜在存在:科学、哲学与社会的交织
外星生命在地球的潜在存在:科学、哲学与社会的交织 摘要:近年来,关于外星生命是否存在的讨论日益激烈。有研究表明,外星人可能已经在地球漫步,这一观点引发了广泛的科学、哲学和社会学思考。本文将从科学角度探讨外星…...
使用FRP 0.58版本进行内网穿透的详细教程
什么是FRP? FRP(Fast Reverse Proxy)是一款高性能的反向代理应用,主要用于内网穿透。通过FRP,您可以将内网服务暴露给外网用户,无需进行复杂的网络配置。 准备工作 服务器:一台具备公网IP的服…...
0000电子技术基础概述
数电 未来课的基础 以前是模块、器件级 现在是 系统级 价格、性能、 技术更新快速的好处:得到了实惠 坏处:工程师需要不断地学习,不变就容易out,要用发展的眼光看待问题 了解基础知识、还要有前沿概念。 理论课、实践课要相结…...
vscode+platformio使用STC官方库进行51单片机开发 -- 中断异常
问题描述 在进行STC8H1K08单片机的开发时,使用官方提供的C语言库函数,在vscodeplatformio开发环境下发现库函数的串口中断异常,看起来像是中断没有触发。 解决过程 用串口中断时一直没有触发中断,起初没有怀疑是中断的问题&…...
探索Android架构设计
Android 应用架构设计探索:MVC、MVP、MVVM和组件化 MVC、MVP和MVVM是常见的三种架构设计模式,当前MVP和MVVM的使用相对比较广泛,当然MVC也并没有过时之说。而所谓的组件化就是指将应用根据业务需求划分成各个模块来进行开发,每个…...
基于matlab的不同边缘检测算子的边缘检测
1 原理 1.1 边缘检测概述 边缘检测是图像处理和计算机视觉中的基本问题,其目的在于标识数字图像中亮度变化明显的点。这些变化通常反映了图像属性的重要事件和变化,如深度不连续、表面方向不连续、物质属性变化和场景照明变化等。边缘检测在特征提取中…...
CentOS安装ntp时间同步服务
CentOS安装ntp时间同步服务 安装ntp 检查服务器是否安装ntp: rpm -q ntp安装ntp: yum install -y ntp服务端配置 配置文件路径:/etc/ntp.conf 设置ntp为开机启动 systemctl enable ntpd查看ntp开机启动状态 enabled:开启, disabled:关闭 …...
【Linux进阶】UNIX体系结构分解——操作系统,内核,shell
1.什么是操作系统? 从严格意义上说,可将操作系统定义为一种软件,它控制计算机硬件资源,提供程序运行环境。我们通常将这种软件称为内核(kerel),因为它相对较小,而且位于环境的核心。 从广义上…...
PageOffice国产版在线编辑word文件
PageOffice国产版支持统信UOS、银河麒麟等国产操作系统。调用客户端WPS在线编辑word、excel、ppt等文件。在线编辑效果与本地WPS一致。如图所示: web系统集成pageofficeV6.0国产版的文档:PageOfficeV6.0国产版最简集成代码(Springboot) PageOffice最简集…...
Bitmap位图数据排列方式
读取dicom C# 使用fo-dicom操作dicom文件-CSDN博客 创建位图 通过读取dicom得到像素内存,本例单指彩色图像。 Bitmap dataBmp new Bitmap(imageWidth, imageHeight, stride, PixelFormat.Format24bppRgb, dstBmp); 当像素的内存按照RGB的排列模式时,…...
重磅消息:ONLYOFFICE8.1版本桌面编辑器发布:功能完善的 PDF 编辑器、幻灯片版式、改进从右至左显示、新的本地化选项等
目录 ONLYOFFICE介绍 PDF 编辑器 功能全面的 PDF 编辑器 文本编辑 页面处理 (添加、旋转、删除) 插入和调整各种对象,例如表格、形状、文本框、图像、TextArt、超链接、方程等。 此外 PDF 表单 文本文档编辑器更新内容 页面颜色 页面…...
16进制数按位修改
16进制数需要按位修改,特别是在修改寄存器的时候 16进制数转换为2进制 #16进制数转换为2进制 def hex_to_binary(hex_value):return bin((hex_value))二进制数转换为列表 def bin_to_array(bin_str):integer = int(bin_str, 2)array...
深度神经网络——什么是小样本学习?
引言 小样本学习是指使用极少量的训练数据来开发人工智能模型的各种算法和技术。小样本学习致力于让人工智能模型在接触相对较少的训练实例后识别和分类新数据。小样本训练与训练机器学习模型的传统方法形成鲜明对比,传统方法通常使用大量训练数据。小样本学习是 主…...
送物机器人电子方案定制
这是一款集娱乐、教育和互动于一身的高科技产品。 一、它的主要功能包括: 1. 智能对话:机器人可以进行简单的对话,回答用户的问题,提供有趣的互动体验。 2. 前进、后退、左转、右转、滑行:机器人可以通过遥控器或AP…...
chatgpt: linux 下用纯c 编写一按钮,当按钮按下在一新窗口显示本机主目录下图片子目录中的1.jpg图片
tmd,这chatgpt太强大了。 从下面的c程序与python程序对比,纯c的ui编程也不是太复杂。 再说一次,要想学好编程必须要用上这个chatgpt工具。 在 Linux 环境下使用纯 C 语言编写一个按钮,当按钮按下时,在一个新窗口中显示本机主目…...
福建城乡建设部网站首页/seo推广培训费用
最近自己开始重新学习java基础了,做java开发不可避免要处理数据库,由于好久不写java了,对idea也有点陌生了。所以这里写篇用jdbc来连接mysql的文章至于mysql怎么装,请自行百度不多说先看代码import java.sql.Connection;import ja…...
绑定ip地址的网站/ai智能搜索引擎
一直都是在自己IIS上部署的,第一次部署MVC项目到共享主机,遇到了些问题。如果你也遇到过类似下图的问题,希望这篇文章对你有些帮助。 首先, 到 IIS management 设置IIS: 7.0 and ASP.Net Runtime Version: 4.0 , 然后到高级选项确…...
郑州建设网站费用/棋牌软件制作开发多少钱
从最开始的,SSH到SpringMVC,随着Spring的发展,使得开发越来越容易了,SpringBoot已经成为Java程序员必会的一项,以下给小伙伴整理了30道相关面试题,也可以作为知识点,学习收藏起来。1.什么是Spri…...
宁波企业自助建站系统/线上推广策划方案范文
由于浏览器的安全限制,网络连接的跨域访问时不被允许的,当然其中也包括了XmlHttpRequest。但是,有些时候我们需要通过跨域访问来获取一些资源,例如: 作为用户,我们需要在自己的网站用AJAX调用一些其他网站提…...
站酷网手机版/国内比较好的软文网站
目录五、Python爬虫的抓取网页5.1 导入所需模块5.2 获取目标URL地址5.3 向目标URL发送请求5.4 保存为本地文件5.5 优化程序五、Python爬虫的抓取网页 Python 爬虫应用案例:爬取目标的网页,并将其保存到本地。 对要编写的爬虫程序进行分析,可…...
百度网站审核期时间/北京seo课程
在此,我将Oracle中的约束总结为6种,即: lNOT NULL约束 DEFAULT约束 (DEFAULT在Oracle中好象没有被作为约束处理,因为创建后从USER_CONSTRAINTS中查不到,有谁知道怎么查,还望不吝赐教)lPRIMARY KEY约束 ll…...