Commit 16c3516a authored by 17322369953's avatar 17322369953
Browse files

air框架改造-登录案例改造

parent 9f105e0a
......@@ -2,7 +2,7 @@
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="D:\python\python.exe" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="Python 3.7" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="D:\python\python.exe" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7" project-jdk-type="Python SDK" />
</project>
\ No newline at end of file
# author:qinguanglei
# ddate:2023/11/21 17:12
from common.dbutils import SQLHelper
from common.logger import log
class SwitchAction(object):
def close_relate_verify(self):
def close_relate_verify(self, company_code):
# 前关联交易结果
curr = SQLHelper.fetch_one(
'select COMPANY_CODE, F_RELATION_CHECK_LEVEL from F_RELATION_CHECK_LEVEL where COMPANY_CODE = %s',
[company_code])
log.info(f'当前关联交易结果:{curr}')
# 关闭关联交易验证,常规测试,关闭该校验
pass
SQLHelper.update_one('update BO_EU_BSI_COMPANY set F_RELATION_CHECK_LEVEL = %s where COMPANY_CODE = %s',
[" ", company_code])
now = SQLHelper.fetch_one(
'select COMPANY_CODE, F_RELATION_CHECK_LEVEL from F_RELATION_CHECK_LEVEL where COMPANY_CODE = %s',
[company_code])
# 关闭关联交易后结果
log.info(f'关闭关联交易结果:{now}')
def open_relate_verify(self):
def open_relate_verify(self, company_code, level):
# 打开关联交易验证
pass
# 当前关联交易结果
curr = SQLHelper.fetch_one(
'select COMPANY_CODE, F_RELATION_CHECK_LEVEL from F_RELATION_CHECK_LEVEL where COMPANY_CODE = %s',
[company_code])
log.info(f'当前关联交易结果:{curr}')
# 关闭关联交易验证,常规测试,关闭该校验
SQLHelper.update_one('update BO_EU_BSI_COMPANY set F_RELATION_CHECK_LEVEL = %s where COMPANY_CODE = %s',
[level, company_code])
now = SQLHelper.fetch_one(
'select COMPANY_CODE, F_RELATION_CHECK_LEVEL from F_RELATION_CHECK_LEVEL where COMPANY_CODE = %s',
[company_code])
# 关闭关联交易后结果
log.info(f'打开关联交易结果:{now}')
def close_license_verify(self):
# 关闭证照校验,常规测试,关闭该校验
......@@ -19,10 +45,35 @@ class SwitchAction(object):
# 打开证照校验
pass
def close_credit_control(self):
def close_credit_control(self, company_address):
# 关闭信用管控,常规测试,关闭该校验
# 当前信用管控结果
curr = SQLHelper.fetch_one(
'select COMPANY_ADDRESS, LIMIT_CONTROL,PAYDAYS from BO_EU_BSI_CREDIT_CONSTANT where COMPANY_ADDRESS = %s',
[company_address])
log.info(f'当前信用管控结果:{curr}')
SQLHelper.update_one(
'update BO_EU_BSI_CREDIT_CONSTANT set LIMIT_CONTROL = %s and PAYDAYS = %s where COMPANY_ADDRESS = %s',
["N", "N", company_address])
# 关闭后信用管控结果
now = SQLHelper.fetch_one(
'select COMPANY_ADDRESS, LIMIT_CONTROL,PAYDAYS from BO_EU_BSI_CREDIT_CONSTANT where COMPANY_ADDRESS = %s',
[company_address])
log.info(f'关闭后信用管控结果:{curr}')
pass
def open_credit_control(self):
def open_credit_control(self, company_address, limit_control, paydays):
# 打开信用管控
pass
# 当前信用管控结果
curr = SQLHelper.fetch_one(
'select COMPANY_ADDRESS, LIMIT_CONTROL,PAYDAYS from BO_EU_BSI_CREDIT_CONSTANT where COMPANY_ADDRESS = %s',
[company_address])
log.info(f'当前信用管控结果:{curr}')
SQLHelper.update_one(
'update BO_EU_BSI_CREDIT_CONSTANT set LIMIT_CONTROL = %s and PAYDAYS = %s where COMPANY_ADDRESS = %s',
[limit_control, paydays, company_address])
# 关闭后信用管控结果
now = SQLHelper.fetch_one(
'select COMPANY_ADDRESS, LIMIT_CONTROL,PAYDAYS from BO_EU_BSI_CREDIT_CONSTANT where COMPANY_ADDRESS = %s',
[company_address])
log.info(f'打开后信用管控结果:{now}')
# author:qinguanglei
# ddate:2023/11/17 15:54
"""
case_tag:case,case_login,case_login_no_input_userid
"""
from selenium import webdriver
from test_login.steps_login import StepsLogin
option = webdriver.ChromeOptions()
# option.add_experimental_option("detach", True) # 设置不要自动关闭浏览器
# 获取驱动器
driver = webdriver.Chrome(options=option)
# 最大化页面
driver.maximize_window()
# 载入步骤集合
steps_login = StepsLogin(driver)
# 打开浏览器
steps_login.open_browser()
# 输入账号密码,只输入密码
steps_login.enter_account_password(2)
# 输入验证码,输入正确的验证码
steps_login.enter_verify_code(0)
# 点击登录
steps_login.click_login_button()
# 判断结果
steps_login.judge_result_error(2)
# author:qinguanglei
# ddate:2023/11/20 9:56
"""
case_tag:case,case_login,case_login_no_input_verifycode
"""
from selenium import webdriver
from test_login.steps_login import StepsLogin
"""家庭作业"""
option = webdriver.ChromeOptions()
# option.add_experimental_option("detach", True) # 设置不要自动关闭浏览器
# 获取驱动器
driver = webdriver.Chrome(options=option)
# 最大化页面
driver.maximize_window()
"""开始执行案例"""
# 载入步骤集合
steps_login = StepsLogin(driver)
# 打开浏览器
steps_login.open_browser()
# 输入账号密码,都输入正确的
steps_login.enter_account_password(0)
# 输入验证码,不输入验证码
steps_login.enter_verify_code(2)
# 点击登录
steps_login.click_login_button()
# 判断结果
steps_login.judge_result_error(3)
# author:qinguanglei
# ddate:2023/11/20 9:43
"""
case_tag:case,case_login,case_login_password_error
"""
from selenium import webdriver
from test_login.steps_login import StepsLogin
"""家庭作业"""
option = webdriver.ChromeOptions()
# option.add_experimental_option("detach", True) # 设置不要自动关闭浏览器
# 获取驱动器
driver = webdriver.Chrome(options=option)
# 最大化页面
driver.maximize_window()
"""开始执行案例"""
# 载入步骤集合
steps_login = StepsLogin(driver)
# 打开浏览器
steps_login.open_browser()
# 输入账号密码,密码输入错误
steps_login.enter_account_password(4)
# 输入验证码,输入正确的验证码
steps_login.enter_verify_code(0)
# 点击登录
steps_login.click_login_button()
# 判断结果
steps_login.judge_result_error(1)
# author:qinguanglei
# ddate:2023/11/16 11:18
"""
case_tag:case,case_login,case_login_success
"""
from selenium import webdriver
from test_login.steps_login import StepsLogin
"""家庭作业"""
option = webdriver.ChromeOptions()
# option.add_experimental_option("detach", True) # 设置不要自动关闭浏览器
# 获取驱动器
driver = webdriver.Chrome(options=option)
# 最大化页面
driver.maximize_window()
"""开始执行案例"""
# 载入步骤集合
steps_login = StepsLogin(driver)
# 打开浏览器
steps_login.open_browser()
# 输入账号密码,账号与密码都输入
steps_login.enter_account_password(0)
# 输入验证码,正确的验证码
steps_login.enter_verify_code(0)
# 点击登录
steps_login.click_login_button()
# 判断结果
steps_login.judge_result()
# author:qinguanglei
# ddate:2023/11/20 9:23
"""
case_tag:case,case_login,case_login_userid_error
"""
from selenium import webdriver
from test_login.steps_login import StepsLogin
"""家庭作业"""
option = webdriver.ChromeOptions()
# option.add_experimental_option("detach", True) # 设置不要自动关闭浏览器
# 获取驱动器
driver = webdriver.Chrome(options=option)
# 最大化页面
driver.maximize_window()
"""开始执行案例"""
# 载入步骤集合
steps_login = StepsLogin(driver)
# 打开浏览器
steps_login.open_browser()
# 输入账号密码,用户名输入错误
steps_login.enter_account_password(3)
# 输入验证码,输入正确的验证码
steps_login.enter_verify_code(0)
# 点击登录
steps_login.click_login_button()
# 判断结果
steps_login.judge_result_error(1)
# author:qinguanglei
# ddate:2023/11/16 16:40
"""
case_tag:case,case_login,case_login_verify_code_error
"""
from selenium import webdriver
from test_login.steps_login import StepsLogin
"""家庭作业"""
option = webdriver.ChromeOptions()
# option.add_experimental_option("detach", True) # 设置不要自动关闭浏览器
# 获取驱动器
driver = webdriver.Chrome(options=option)
# 最大化页面
driver.maximize_window()
"""开始执行案例"""
# 载入步骤集合
steps_login = StepsLogin(driver)
# 打开浏览器
steps_login.open_browser()
# 输入账号密码,都输入正确的
steps_login.enter_account_password(0)
# 输入验证码,错误的验证码
steps_login.enter_verify_code(1)
# 点击登录
steps_login.click_login_button()
# 判断结果
steps_login.judge_result_error(0)
import re
import os
def get_message(case_path, case_name):
"""
从注释中获取某个文件的 case tag 信息
"""
tags = []
pyfile = open(case_path + os.sep + case_name + '.py', 'r', encoding='utf-8')
lines = pyfile.readlines()
for line in lines:
if 'case_tag' in line:
line = line.split('case_tag')[-1]
#对不规范的写法做一些处理,如中文分号, 中文逗号,多空格等。。
line = re.sub(' ', '', line)
line = line.replace(',', ',').replace(':', '').replace(':', '')
line = line.strip().strip('\n')
tags = line.split(',')
pyfile.close()
return tags
def get_case_tag_list(case_path, cases):
"""
遍历case目录下的文件,从文件中获取case tag,加入列表中
再加个判断,判断是跑线上还是线下
"""
tagList = cases.split('#')
env = os.environ['ENV']
case_list = []
for f in os.listdir(case_path):
nf_path = os.path.join(case_path, f)
if os.path.isdir(nf_path) and nf_path.endswith(".air") == False:
for nf in os.listdir(nf_path):
script = os.path.join(nf_path, nf)
if script.endswith(".air"):
air_name = nf.replace('.air', '')
case_tags = get_message(script, air_name)
flag = False
for con in tagList:
conList = con.split(',')
if list(set(case_tags) & set(conList)):
flag = True
else:
flag = False
break
if flag and (env in case_tags or env in ('sit', 'sita')):
case_hash = {}
case_hash["air_path"] = str(script)
case_hash["air_name"] = str(air_name)
case_hash["module"] = str(script.split(os.sep)[-2])
case_list.append(case_hash)
else:
script = os.path.join(case_path, f)
if f.endswith(".air"):
air_name = f.replace('.air', '')
case_tags = get_message(script, air_name)
flag = False
for con in tagList:
conList = con.split(',')
if list(set(case_tags) & set(conList)):
flag = True
else:
flag = False
break
if flag and (env in case_tags or env in ('sit', 'sita')):
case_hash = {}
case_hash["air_path"] = str(script)
case_hash["air_name"] = str(air_name)
case_hash["module"] = str(script.split(os.sep)[-2])
case_list.append(case_hash)
return case_list
def get_case_tag_list_2(case_path, cases):
"""
遍历case目录下的文件,从文件中获取case tag,加入列表中
"""
tagList = cases.split('#')
case_list = []
for f in os.listdir(case_path):
script = os.path.join(case_path, f)
air_name = f.replace('.air', '')
case_tags = get_message(script, air_name)
flag = False
for con in tagList:
conList = con.split(',')
if list(set(case_tags) & set(conList)):
flag = True
else:
flag = False
break
if flag:
case_list.append(air_name)
return case_list
# -*- coding: utf-8 -*-
import unittest
import os
import sys
import six
import re
import shutil
import traceback
import warnings
from io import open
from airtest.core.api import G, auto_setup, log
from airtest.core.settings import Settings as ST
from airtest.utils.compat import decode_path, script_dir_name, script_log_dir
from copy import copy
class AirtestCase(unittest.TestCase):
PROJECT_ROOT = "."
SCRIPTEXT = ".air"
TPLEXT = ".png"
@classmethod
def setUpClass(cls):
cls.args = args
setup_by_args(args)
# setup script exec scope
cls.scope = copy(globals())
cls.scope["exec_script"] = cls.exec_other_script
def setUp(self):
if self.args.log and self.args.recording:
for dev in G.DEVICE_LIST:
try:
dev.start_recording()
except:
traceback.print_exc()
def tearDown(self):
if self.args.log and self.args.recording:
for k, dev in enumerate(G.DEVICE_LIST):
try:
output = os.path.join(self.args.log, "recording_%d.mp4" % k)
dev.stop_recording(output)
except:
traceback.print_exc()
def runTest(self):
scriptpath, pyfilename = script_dir_name(self.args.script)
pyfilepath = os.path.join(scriptpath, pyfilename)
pyfilepath = os.path.abspath(pyfilepath)
self.scope["__file__"] = pyfilepath
with open(pyfilepath, 'r', encoding="utf8") as f:
code = f.read()
pyfilepath = pyfilepath.encode(sys.getfilesystemencoding())
try:
exec(compile(code.encode("utf-8"), pyfilepath, 'exec'), self.scope)
except Exception as err:
tb = traceback.format_exc()
log("Final Error", tb)
six.reraise(*sys.exc_info())
@classmethod
def exec_other_script(cls, scriptpath):
"""run other script in test script"""
warnings.simplefilter("always")
warnings.warn("please use using() api instead.", PendingDeprecationWarning)
def _sub_dir_name(scriptname):
dirname = os.path.splitdrive(os.path.normpath(scriptname))[-1]
dirname = dirname.strip(os.path.sep).replace(os.path.sep, "_").replace(cls.SCRIPTEXT, "_sub")
return dirname
def _copy_script(src, dst):
if os.path.isdir(dst):
shutil.rmtree(dst, ignore_errors=True)
os.mkdir(dst)
for f in os.listdir(src):
srcfile = os.path.join(src, f)
if not (os.path.isfile(srcfile) and f.endswith(cls.TPLEXT)):
continue
dstfile = os.path.join(dst, f)
shutil.copy(srcfile, dstfile)
# find script in PROJECT_ROOT
scriptpath = os.path.join(ST.PROJECT_ROOT, scriptpath)
# copy submodule's images into sub_dir
sub_dir = _sub_dir_name(scriptpath)
sub_dirpath = os.path.join(cls.args.script, sub_dir)
_copy_script(scriptpath, sub_dirpath)
# read code
pyfilename = os.path.basename(scriptpath).replace(cls.SCRIPTEXT, ".py")
pyfilepath = os.path.join(scriptpath, pyfilename)
pyfilepath = os.path.abspath(pyfilepath)
with open(pyfilepath, 'r', encoding='utf8') as f:
code = f.read()
# replace tpl filepath with filepath in sub_dir
code = re.sub("[\'\"](\w+.png)[\'\"]", "\"%s/\g<1>\"" % sub_dir, code)
exec(compile(code.encode("utf8"), pyfilepath, 'exec'), cls.scope)
def setup_by_args(args):
# init devices
if isinstance(args.device, list):
devices = args.device
elif args.device:
devices = [args.device]
else:
devices = []
# set base dir to find tpl
dirpath, _ = script_dir_name(args.script)
# set log dir
if args.log:
args.log = script_log_dir(dirpath, args.log)
print("save log in '%s'" % args.log)
else:
print("do not save log")
# guess project_root to be basedir of current .air path
project_root = os.path.dirname(args.script) if not ST.PROJECT_ROOT else None
try:
auto_setup(dirpath, devices, args.log, project_root)
except:
os.system('adb devices')
auto_setup(dirpath, devices, args.log, project_root)
def run_script(parsed_args, testcase_cls=AirtestCase):
global args # make it global deliberately to be used in AirtestCase & test scripts
args = parsed_args
suite = unittest.TestSuite()
suite.addTest(testcase_cls())
result = unittest.TextTestRunner(verbosity=0).run(suite)
if not result.wasSuccessful():
sys.exit(-1)
class ModuleName(object):
SEARCH_MERGER = "search-merger"
SEARCH_SUGGEST = "search-suggest"
SEARCH_PLATFORM_INDEX = "search-platform-index"
SEARCH_PLATFORM_WEB = "search-platform-web"
import configparser
import os
import yaml
cf = configparser.ConfigParser()
curPath = os.path.abspath(os.path.dirname(__file__))
rootPath = rootPath = os.path.split(curPath)[0]
class confOP:
def getConfValue(self, filename, section, option, type='string'):
cf.read(filename)
if (type == 'string'):
value = cf.get(section, option)
else:
value = cf.getint(section, option)
return value
def getYamlValue(self, filename):
"""
获取公共sql中的sql
:param filename:
:return:
"""
file = os.path.join(rootPath, "data" + os.sep + filename)
f = open(file, 'r', encoding='utf-8')
cont = f.read()
value = yaml.load(cont, Loader=yaml.FullLoader)
f.close()
return value
def getBusiYamlValue(self, path, filename):
"""
获取业务中的yaml文件数据
:param path:
:param filename:
:return:
"""
file = os.path.join(path, filename)
f = open(file, 'r', encoding='utf-8')
cont = f.read()
value = yaml.load(cont, Loader=yaml.FullLoader)
f.close()
return value
[meitun_db]
host = rm-bp18as20m3solyi69.mysql.rds.aliyuncs.com
port = 3306
user = test_admin
password = ahdp0b.cr76_Pje1
[bj_db]
host = 172.25.1.6
port = 3320
user = local_rw
password = baidugoogleyahoo
[promotion]
livedb = 19
liveenv = 4
liveserver = 129
predb = 19
preenv = 2
preserver = 58
[mongo]
ip = 127.0.0.1
port = 27017
[redis]
redis_host=192.168.24.31
import pymysql
import os
import sys
from common.confop import confOP
from common.db.sql.sqlByIdb import sqlByIdb
import pymongo
curPath = os.path.abspath(os.path.dirname(__file__))
rootPath = os.path.split(curPath)[0]
sys.path.append(rootPath)
class dbOP():
def __init__(self, path=rootPath):
self.path = path
def selectSql(self, schema, param=[], db="bj_db"):
host = mySql().getConf(db)[0]
port = mySql().getConf(db)[1]
user = mySql().getConf(db)[2]
pwd = mySql().getConf(db)[3]
value = confOP().getYamlValue("sql")
if schema not in value:
value = confOP().getBusiYamlValue(self.path, "sql")
env = os.environ["ENV"]
if env == "on" or env == "pre":
database = value[schema][0]
sql = value[schema][1]
param = param
result = sqlByIdb().selectSql(database, sql, param, env)
else:
result = mySql().selectSql(host, port, user, pwd, value[schema][0], value[schema][1], param)
return result
def ddlSql(self, schema, param=[], db="bj_db"):
host = mySql().getConf(db)[0]
port = mySql().getConf(db)[1]
user = mySql().getConf(db)[2]
pwd = mySql().getConf(db)[3]
value = confOP().getYamlValue("sql")
if schema not in value:
value = confOP().getBusiYamlValue(self.path, "sql")
result = mySql().executeUpdate(host, port, user, pwd, value[schema][0], value[schema][1], param)
return result
class mySql:
def __init__(self):
pass
def getConf(self, db="bj_db"):
host = confOP().getConfValue(curPath + "/conf.ini", db, "host")
port = confOP().getConfValue(curPath + "/conf.ini", db, "port", "int")
user = confOP().getConfValue(curPath + "/conf.ini", db, "user")
pwd = confOP().getConfValue(curPath + "/conf.ini", db, "password")
return host,port,user,pwd
def connection(self, host, port, user, pwd, database):
return pymysql.connect(host=host, port=port,user=user,passwd=pwd,db=database)
def selectSql(self, host, port, user, pwd, database, sql, param=[]):
conn = self.connection(host, port, user, pwd, database)
cursor = conn.cursor()
try:
cursor.execute(sql, param)
data = cursor.fetchall()
cols = cursor.description
col = []
for i in cols:
col.append(i[0])
data = list(map(list, data))
return data
except Exception as e:
print(e)
conn.rollback()
cursor.close()
conn.close()
def executeUpdate(self, host, port, user, pwd, database, sql, param=[]):
conn = self.connection(host, port, user, pwd, database)
cursor = conn.cursor()
try:
ret = cursor.execute(sql, param)
conn.commit()
return ret
except Exception as e:
print(e)
conn.rollback()
cursor.close()
conn.close()
class mongodb:
def connection(self,db,collect):
ip = confOP().getConfValue(curPath + "/conf.ini", "mongo", "ip")
port = confOP().getConfValue(curPath + "/conf.ini", "mongo", "port")
path = "mongodb://" + ip + ":" + port + "/"
myclient = pymongo.MongoClient(path)
mydb = myclient[db]
mycol = mydb[collect]
return mycol
#查询所有的值
def findALl(self, db, collect):
result = []
mycol = self.connection(db, collect)
for x in mycol.find():
result.append(x)
return result
#按照条件查询:条件为{}类型
def findByCon(self, db, collect, condition):
result = []
mycol = self.connection(db, collect)
for x in mycol.find(condition):
result.append(x)
return result
if __name__ == '__main__':
env = 'sit'
os.environ['ENV'] = env.lower()
path = "D:\\myCode\\autotest-airtest-local\\data\\月嫂"
#mysql的例子
result = dbOP(path).selectSql("local_worker_info")
print(result[0])
#monggdb的例子
#mongodb().findByCon("yapi","user", {"role": "admin"})
#redis的例子
#redisClass().connect()
import redis
import os
curPath = os.path.abspath(os.path.dirname(__file__))
rootPath = os.path.split(curPath)[0]
import sys
sys.path.append(rootPath)
from common.confop import confOP
class redisClass:
def connect(self):
redis_host = confOP.getConfValue(curPath + "/conf.ini", "redis", "redis_host")
pool = redis.ConnectionPool(host=redis_host)
r = redis.Redis(connection_pool=pool)
return r
def randomkey(self):
"""
获取随机的一个键
:return: b'name'
"""
r = redisClass().connect()
return r.randomkey()
def exists(self, name):
"""
判断一个键是否存在
:param name:键名
:return: True
例子: .exists('name')
是否存在name这个键
"""
r = redisClass().connect()
return r.exists(name)
def delete(self, name):
"""
删除一个键
:param name:键名
:return: 1
例子: .delete('name')
删除name这个键
"""
r = redisClass().connect()
return r.delete(name)
def type(self, name):
"""
判断键类型
:param name:
:return:b'string'
例子:.type('name')
判断name这个键类型
"""
r = redisClass().connect()
return r.type(name)
def keys(self, pattern):
"""
获取所有符合规则的键
:param pattern:匹配规则
:return:[b'name']
例子:.keys('n*')
获取所有以n开头的键
"""
r = redisClass().connect()
return r.keys(pattern)
def rename(self, src, dst):
"""
重命名键
:param src: 原键名;
:param dst: 新键名
:return:True
例子:.rename('name', 'nickname')
将name重命名为nickname
"""
r = redisClass().connect()
return r.rename(src, dst)
def dbsize(self):
"""
获取当前数据库中键的数目
:return: 100
"""
r = redisClass().connect()
return r.dbsize()
def expire(self, name, time):
"""
设定键的过期时间,单位为秒
:param name:键名;
:param time:秒数
:return:True
例子:.expire('name', 2)
将name键的过期时间设置为2秒
"""
r = redisClass().connect()
return r.expire(name, time)
def ttl(self, name):
"""
获取键的过期时间,单位为秒,-1表示永久不过期
:param name: 键名
:return: -1
例子:.ttl('name')
获取name这个键的过期时间
"""
r = redisClass().connect()
return r.ttl(name)
def move(self, name, db):
"""
将键移动到其他数据库
:param name: 键名;
:param db: 数据库代号
:return: True
例子: .move('name', 2)
将name移动到2号数据库
"""
r = redisClass().connect()
return r.move(name, db)
def flushdb(self):
"""
删除当前选择数据库中的所有键
:return: True
"""
r = redisClass().connect()
return r.flushdb()
def flushall(self):
"""
删除所有数据库中的所有键
:return: True
"""
r = redisClass().connect()
return r.flushall()
def set(self, name, value):
"""
给数据库中键为name的string赋予值value
:param name: 键名;
:param value:值
:return: True
例子: .set('name', 'Bob')
给name这个键的value赋值为Bob
"""
r = redisClass().connect()
return r.set(name, value)
def get(self, name):
"""
返回数据库中键为name的string的value
:param name: 键名
:return: b'Bob'
例子: .get('name')
返回name这个键的value
"""
r = redisClass().connect()
return r.get(name)
def getset(self, name, value):
"""
给数据库中键为name的string赋予值value并返回上次的value
:param name: 键名;
:param value: 新值
:return: b'Bob'
例子: .getset('name', 'Mike')
赋值name为Mike并得到上次的value
"""
r = redisClass().connect()
return r.getset(name, value)
def mget(self, keys, *args):
"""
返回多个键对应的value
:param keys: 键的列表
:param args:
:return: [b'Mike', b'Miker']
例子: .mget(['name', 'nickname'])
返回name和nickname的value
"""
r = redisClass().connect()
return r.mget(keys, *args)
def setnx(self, name, value):
"""
如果不存在这个键值对,则更新value,否则不变
:param name: 键名
:param value:
:return: 第一次运行结果是True,第二次运行结果是False
例子: .setnx('newname', 'James')
如果newname这个键不存在,则设置值为James
"""
r = redisClass().connect()
return r.setnx(name, value)
def setex(self, name, time, value):
"""
设置可以对应的值为string类型的value,并指定此键值对应的有效期
:param name: 键名;
:param time: 有效期;
:param value: 值
:return: True
例子: .setex('name', 1, 'James')
将name这个键的值设为James,有效期为1秒
"""
r = redisClass().connect()
return r.setex(name, time, value)
def setrange(self, name, offset, value):
"""
设置指定键的value值的子字符串
:param name: 键名;
:param offset: 偏移量;
:param value: 值
:return:xx,修改后的字符串长度
例子:
.set('name', 'Hello')
.setrange('name', 6, 'World')
设置name为Hello字符串,并在index为6的位置补World
"""
r = redisClass().connect()
return r.setrange(name, offset, value)
def mset(self, mapping):
"""
批量赋值
:param mapping: 字典
:return: True
例子: .mset({'name1': 'Durant', 'name2': 'James'})
将name1设为Durant,name2设为James
"""
r = redisClass().connect()
return r.mset(mapping)
def msetnx(self, mapping):
"""
键均不存在时才批量赋值
:param mapping: 字典
:return: True
例子: .msetnx({'name3': 'Smith', 'name4': 'Curry'})
在name3和name4均不存在的情况下才设置二者值
"""
r = redisClass().connect()
return r.msetnx(mapping)
def incr(self, name, amount=1):
"""
键为name的value增值操作,默认为1,键不存在则被创建并设为amount
:param name: 键名;
:param amount: 增长的值
:return: 1,即修改后的值
例子: .incr('age', 1)
age对应的值增1,若不存在,则会创建并设置为1
"""
r = redisClass().connect()
return r.incr(name, amount)
def decr(self, name, amount=1):
"""
键为name的value减值操作,默认为1,键不存在则被创建并将value设置为-amount
:param name: 键名;
:param amount: 减少的值
:return: -1,即修改后的值
例子: .decr('age', 1)
age对应的值减1,若不存在,则会创建并设置为-1
"""
r = redisClass().connect()
return r.decr(name, amount)
def append(self, key, value):
"""
键为name的string的值附加value
:param key: 键名
:param value:
:return: 13,即修改后的字符串长度
例子: .append('nickname', 'OK')
向键为nickname的值后追加OK
"""
r = redisClass().connect()
return r.append(key, value)
def substr(self, name, start, end=-1):
"""
返回键为name的string的子串
:param name: 键名;
:param start: 起始索引;
:param end: 终止索引,默认为-1,表示截取到末尾
:return: b'ello'
例子:.substr('name', 1, 4)
返回键为name的值的字符串,截取索引为1~4的字符
"""
r = redisClass().connect()
return r.substr(name, start, end)
def getrange(self, key, start, end):
"""
获取键的value值从start到end的子字符串
:param key: 键名;
:param start: 起始索引;
:param end: 终止索引
:return: b'ello'
例子: .getrange('name', 1, 4)
返回键为name的值的字符串,截取索引为1~4的字符
"""
r = redisClass().connect()
return r.getrange(key, start, end)
def rpush(self, name, *values):
"""
在键为name的列表末尾添加值为value的元素,可以传多个
:param name: 键名;
:param values: 值
:return: 3,列表大小
例子: .rpush('list', 1, 2, 3)
向键为list的列表尾添加1、2、3
"""
r = redisClass().connect()
return r.rpush(name, *values)
def lpush(self, name, *values):
"""
在键为name的列表头添加值为value的元素,可以传多个
:param name: 键名;
:param values: 值
:return: 4,列表大小
例子:.lpush('list', 0)
向键为list的列表头部添加0
"""
r = redisClass().connect()
return r.lpush(name, *values)
def llen(self, name):
"""
返回键为name的列表的长度
:param name: 键名
:return: 4
例子:.llen('list')
返回键为list的列表的长度
"""
r = redisClass().connect()
return r.llen(name)
def lrange(self, name, start, end):
"""
返回键为name的列表中start至end之间的元素
:param name: 键名;
:param start: 起始索引;
:param end: 终止索引
:return: [b'3', b'2', b'1']
例子:.lrange('list', 1, 3)
返回起始索引为1终止索引为3的索引范围对应的列表
"""
r = redisClass().connect()
return r.lrange(name, start, end)
def ltrim(self, name, start, end):
"""
截取键为name的列表,保留索引为start到end的内容
:param name: 键名;
:param start: 起始索引;
:param end: 终止索引
:return: True
例子:ltrim('list', 1, 3)
保留键为list的索引为1到3的元素
"""
r = redisClass().connect()
return r.ltrim(name, start, end)
def lindex(self, name, index):
"""
返回键为name的列表中index位置的元素
:param name: 键名;
:param index: 索引
:return: b’2’
例子:.lindex('list', 1)
返回键为list的列表索引为1的元素
"""
r = redisClass().connect()
return r.lindex(name, index)
def lset(self, name, index, value):
"""
给键为name的列表中index位置的元素赋值,越界则报错
:param name: 键名;
:param index: 索引位置;
:param value: 值
:return: True
例子:.lset('list', 1, 5)
将键为list的列表中索引为1的位置赋值为5
"""
r = redisClass().connect()
return r.lset(name, index, value)
def lrem(self, name, count, value):
"""
删除count个键的列表中值为value的元素
:param name: 键名;
:param count: 删除个数;
:param value: 值
:return: 1,即删除的个数
例子:.lrem('list', 2, 3)
将键为list的列表删除两个3
"""
r = redisClass().connect()
return r.lrem(name, count, value)
def lpop(self, name):
"""
返回并删除键为name的列表中的首元素
:param name: 键名
:return: b'5'
例子:.lpop('list')
返回并删除名为list的列表中的第一个元素
"""
r = redisClass().connect()
return r.lpop(name)
def rpop(self, name):
"""
返回并删除键为name的列表中的尾元素
:param name: 键名
:return: b'2'
例子:.rpop('list')
返回并删除名为list的列表中的最后一个元素
"""
r = redisClass().connect()
return r.rpop(name)
def blpop(self, keys, timeout=0):
"""
返回并删除名称在keys中的list中的首个元素,如果列表为空,则会一直阻塞等待
:param keys: 键列表;
:param timeout: 超时等待时间,0为一直等待
:return: [b'5']
例子:.blpop('list')
返回并删除键为list的列表中的第一个元素
"""
r = redisClass().connect()
return r.blpop(keys, timeout)
def brpop(self, keys, timeout=0):
"""
返回并删除键为name的列表中的尾元素,如果list为空,则会一直阻塞等待
:param keys: 键列表;
:param timeout: 超时等待时间,0为一直等待
:return: [b'2']
例子:.brpop('list')
返回并删除名为list的列表中的最后一个元素
"""
r = redisClass().connect()
return r.brpop(keys, timeout)
def rpoplpush(self, src, dst):
"""
返回并删除名称为src的列表的尾元素,并将该元素添加到名称为dst的列表头部
:param src: 源列表的键;
:param dst: 目标列表的key
:return: b'2'
例子:.rpoplpush('list', 'list2')
将键为list的列表尾元素删除并将其添加到键为list2的列表头部,然后返回
"""
r = redisClass().connect()
return r.rpoplpush(src, dst)
def sadd(self, name, *values):
"""
向键为name的集合中添加元素
:param name: 键名;
:param values: 值,可为多个
:return: 3,即插入的数据个数
例子: .sadd('tags', 'Book', 'Tea', 'Coffee')
向键为tags的集合中添加Book、Tea和Coffee这3个内容
"""
r = redisClass().connect()
return r.sadd(name, *values)
def srem(self, name, *values):
"""
从键为name的集合中删除元素
:param name: 键名;
:param values: 值,可为多个
:return: 1,即删除的数据个数
例子: .srem('tags', 'Book')
从键为tags的集合中删除Book
"""
r = redisClass().connect()
return r.srem(name, *values)
def spop(self, name):
"""
随机返回并删除键为name的集合中的一个元素
:param name: 键名
:return:b'Tea'
例子:.spop('tags')
从键为tags的集合中随机删除并返回该元素
"""
r = redisClass().connect()
return r.spop(name)
def smove(self, src, dst, value):
"""
从src对应的集合中移除元素并将其添加到dst对应的集合中
:param src: 源集合;
:param dst: 目标集合;
:param value: 元素值
:return: True
例子:.smove('tags', 'tags2', 'Coffee')
从键为tags的集合中删除元素Coffee并将其添加到键为tags2的集合
"""
r = redisClass().connect()
return r.smove(src, dst, value)
def scard(self, name):
"""
返回键为name的集合的元素个数
:param name:
:return: 3
例子:.scard('tags')
获取键为tags的集合中的元素个数
"""
r = redisClass().connect()
return r.scard(name)
def sismember(self, name, value):
"""
测试member是否是键为name的集合的元素
:param name: 键值
:param value:
:return: True
例子:.sismember('tags', 'Book')
判断Book是否是键为tags的集合元素
"""
r = redisClass().connect()
return r.sismember(name, value)
def sinter(self, keys, *args):
"""
返回所有给定键的集合的交集
:param keys: 键列表
:param args:
:return: {b'Coffee'}
例子:.sinter(['tags', 'tags2'])
返回键为tags的集合和键为tags2的集合的交集
"""
r = redisClass().connect()
return r.sinter(keys, *args)
def sinterstore(self, dest, keys, *args):
"""
求交集并将交集保存到dest的集合
:param dest: 结果集合;
:param keys: 键列表
:param args:
:return: 1
例子:.sinterstore('inttag', ['tags', 'tags2'])
求键为tags的集合和键为tags2的集合的交集并将其保存为inttag
"""
r = redisClass().connect()
return r.sinterstore(dest, keys, *args)
def sunion(self, keys, *args):
"""
返回所有给定键的集合的并集
:param keys: 键列表
:param args:
:return: {b'Coffee', b'Book', b'Pen'}
例子:.sunion(['tags', 'tags2'])
返回键为tags的集合和键为tags2的集合的并集
"""
r = redisClass().connect()
return r.sunion(keys, *args)
def sunionstore(self, dest, keys, *args):
"""
求并集并将并集保存到dest的集合
:param dest: 结果集合;
:param keys: 键列表
:param args:
:return: 3
例子:.sunionstore('inttag', ['tags', 'tags2'])
求键为tags的集合和键为tags2的集合的并集并将其保存为inttag
"""
r = redisClass().connect()
return r.sunionstore(dest, keys, *args)
def sdiff(self, keys, *args):
"""
返回所有给定键的集合的差集
:param keys: 键列表
:param args:
:return: {b'Book', b'Pen'}
例子:.sdiff(['tags', 'tags2'])
返回键为tags的集合和键为tags2的集合的差集
"""
r = redisClass().connect()
return r.sdiff(keys, *args)
def sdiffstore(self, dest, keys, *args):
"""
求差集并将差集保存到dest集合
:param dest: 结果集合;
:param keys: 键列表
:param args:
:return: 3
例子:.sdiffstore('inttag', ['tags', 'tags2'])
求键为tags的集合和键为tags2的集合的差集并将其保存为inttag
"""
r = redisClass().connect()
return r.sdiffstore(dest, keys, *args)
def smembers(self, name):
"""
返回键为name的集合的所有元素
:param name: 键名
:return: {b'Pen', b'Book', b'Coffee'}
例子:.smembers('tags')
返回键为tags的集合的所有元素
"""
r = redisClass().connect()
return r.smembers(name)
def srandmember(self, name):
"""
随机返回键为name的集合中的一个元素,但不删除元素
:param name: 键值
:return:
例子:.srandmember('tags')
随机返回键为tags的集合中的一个元素
"""
r = redisClass().connect()
return r.srandmember(name)
def zadd(self, name, *args, **kwargs):
"""
向键为name的zset中添加元素member,score用于排序。如果该元素存在,则更新其顺序
:param name: 键名;
:param args: 可变参数
:param kwargs:
:return: 2,即添加的元素个数
例子:.zadd('grade', 100, 'Bob', 98, 'Mike')
向键为grade的zset中添加Bob(其score为100),并添加Mike(其score为98)
"""
r = redisClass().connect()
return r.zadd(name, *args, **kwargs)
def zrem(self, name, *values):
"""
删除键为name的zset中的元素
:param name: 键名;
:param values: 元素
:return: 1,即删除的元素个数
例子:.zrem('grade', 'Mike')
从键为grade的zset中删除Mike
"""
r = redisClass().connect()
return r.zrem(name, *values)
def zincrby(self, name, value, amount=1):
"""
如果在键为name的zset中已经存在元素value,则将该元素的score增加amount;否则向该集合中添加该元素,其score的值为amount
:param name: key名;
:param value: 元素;
:param amount: 增长的score值
:return: 98.0,即修改后的值
例子:.zincrby('grade', 'Bob', -2)
键为grade的zset中Bob的score减2
"""
r = redisClass().connect()
return r.zincrby(name, value, amount)
def zrank(self, name, value):
"""
返回键为name的zset中元素的排名,按score从小到大排序,即名次
:param name: 键名;
:param value: 元素值
:return: 1
例子:.zrank('grade', 'Amy')
得到键为grade的zset中Amy的排名
"""
r = redisClass().connect()
return r.zrank(name, value)
def zrevrank(self, name, value):
"""
返回键为name的zset中元素的倒数排名(按score从大到小排序),即名次
:param name: 键名;
:param value: 元素值
:return: 2
例子:.zrevrank('grade', 'Amy')
得到键为grade的zset中Amy的倒数排名
"""
r = redisClass().connect()
return r.zrevrank(name, value)
def zrevrange(self, name, start, end, withscores=False):
"""
返回键为name的zset(按score从大到小排序)中index从start到end的所有元素
:param name: 键值;
:param start: 开始索引;
:param end: 结束索引;
:param withscores: 是否带score
:return: [b'Bob', b'Mike', b'Amy', b'James']
例子:.zrevrange('grade', 0, 3)
返回键为grade的zset中前四名元素
"""
r = redisClass().connect()
return r.zrevrange(name, start, end, withscores)
def zrangebyscore(self, name, min, max, start=None, num=None, withscores=False):
"""
返回键为name的zset中score在给定区间的元素
:param name: 键名;
:param min: 最低score;
:param max: 最高score;
:param start: 起始索引;
:param num: 个数;
:param withscores: 是否带score
:return: [b'Bob', b'Mike', b'Amy', b'James']
例子:.zrangebyscore('grade', 80, 95)
返回键为grade的zset中score在80和95之间的元素
"""
r = redisClass().connect()
return r.zrangebyscore(name, min, max, start, num, withscores)
def zcount(self, name, min, max):
"""
返回键为name的zset中score在给定区间的数量
:param name: 键名;
:param min: 最低score;
:param max: 最高score
:return: 2
例子:.zcount('grade', 80, 95)
返回键为grade的zset中score在80到95的元素个数
"""
r = redisClass().connect()
return r.zcount(name, min, max)
def zcard(self, name):
"""
返回键为name的zset的元素个数
:param name: 键名
:return: 3
例子:.zcard('grade')
获取键为grade的zset中元素的个数
"""
r = redisClass().connect()
return r.zcard(name)
def zremrangebyrank(self, name, min, max):
"""
删除键为name的zset中排名在给定区间的元素
:param name: 键名;
:param min: 最低位次;
:param max: 最高位次
:return: 1,即删除的元素个数
例子:.zremrangebyrank('grade', 0, 0)
删除键为grade的zset中排名第一的元素
"""
r = redisClass().connect()
return r.zremrangebyrank(name, min, max)
def zremrangebyscore(self, name, min, max):
"""
删除键为name的zset中score在给定区间的元素
:param name: 键名;
:param min: 最低score;
:param max: 最高score
:return: 1,即删除的元素个数
例子:.zremrangebyscore('grade', 80, 90)
删除score在80到90之间的元素
"""
r = redisClass().connect()
return r.zremrangebyscore(name, min, max)
def hset(self, name, key, value):
"""
向键为name的散列表中添加映射
:param name: 键名;
:param key: 映射键名;
:param value: 映射键值
:return: 1,即添加的映射个数
例子:.hset('price', 'cake', 5)
向键为price的散列表中添加映射关系,cake的值为5
"""
r = redisClass().connect()
return r.hset(name, key, value)
def hsetnx(self, name, key, value):
"""
如果映射键名不存在,则向键为name的散列表中添加映射
:param name: 键名;
:param key: 映射键名;
:param value: 映射键值
:return: 1,即添加的映射个数
例子:.hsetnx('price', 'book', 6)
向键为price的散列表中添加映射关系,book的值为6
"""
r = redisClass().connect()
return r.hsetnx(name, key, value)
def hget(self, name, key):
"""
返回键为name的散列表中key对应的值
:param name: 键名;
:param key: 映射键名;
:return: 5
例子:.hget('price', 'cake')
获取键为price的散列表中键名为cake的值
"""
r = redisClass().connect()
return r.hget(name, key)
def hmget(self, name, keys, *args):
"""
返回键为name的散列表中各个键对应的值
:param name: 键名;
:param keys: 映射键名列表
:param args:
:return: [b'3', b'7']
例子:.hmget('price', ['apple', 'orange'])
获取键为price的散列表中apple和orange的值
"""
r = redisClass().connect()
return r.hmget(name, keys, *args)
def hmset(self, name, mapping):
"""
向键为name的散列表中批量添加映射
:param name: 键名;
:param mapping: 映射字典
:return: True
例子:.hmset('price', {'banana': 2, 'pear': 6})
向键为price的散列表中批量添加映射
"""
r = redisClass().connect()
return r.hmset(name, mapping)
def hincrby(self, name, key, amount=1):
"""
将键为name的散列表中映射的值增加amount
:param name: 键名;
:param key: 映射键名;
:param amount: 增长量
:return: 6,修改后的值
例子:.hincrby('price', 'apple', 3)
key为price的散列表中apple的值增加3
"""
r = redisClass().connect()
return r.hincrby(name, key, amount)
def hexists(self, name, key):
"""
键为name的散列表中是否存在键名为键的映射
:param name: 键名;
:param key: 映射键名;
:return: True
例子:.hexists('price', 'banana')
键为price的散列表中banana的值是否存在
"""
r = redisClass().connect()
return r.hexists(name, key)
def hdel(self, name, *keys):
"""
在键为name的散列表中,删除键名为键的映射
:param name: 键名;
:param key: 映射键名;
:return: True
例子:.hdel('price', 'banana')
从键为price的散列表中删除键名为banana的映射
"""
r = redisClass().connect()
return r.hdel(name, *keys)
def hlen(self, name):
"""
从键为name的散列表中获取映射个数
:param name: 键名
:return: 6
例子:.hlen('price')
从键为price的散列表中获取映射个数
"""
r = redisClass().connect()
return r.hlen(name)
def hkeys(self, name):
"""
从键为name的散列表中获取所有映射键名
:param name: 键名
:return: [b'cake', b'book', b'banana', b'pear']
例子:.hkeys('price')
从键为price的散列表中获取所有映射键名
"""
r = redisClass().connect()
return r.hkeys(name)
def hvals(self, name):
"""
从键为name的散列表中获取所有映射键值
:param name: 键名
:return:[b'5', b'6', b'2', b'6']
例子:.hvals('price')
从键为price的散列表中获取所有映射键值
"""
r = redisClass().connect()
return r.hvals(name)
def hgetall(self, name):
"""
从键为name的散列表中获取所有映射键值对
:param name: 键名
:return:{b'cake': b'5', b'book': b'6', b'orange': b'7', b'pear': b'6'}
例子:.hgetall('price')
从键为price的散列表中获取所有映射键值对
"""
r = redisClass().connect()
return r.hgetall(name)
# -*- encoding=utf8 -*-
import base64
import requests
import json
from common.confop import confOP
class sqlByIdb:
# 登录
def login(self):
url = "http://docp.plt.babytree-inc.com/api/v1/passport/login/"
header = {
'Content-Type': 'application/json'
}
username = "dGVzdF9jbG91ZA=="
password = "eDZpbkRITnJVRWRl"
postdata = json.dumps({
"username": base64.b64decode(username.encode('utf-8')).decode("utf-8"),
"password": base64.b64decode(password.encode('utf-8')).decode("utf-8")
})
response = requests.request("POST", url, headers=header, data=postdata)
result = json.loads(response.text.encode('utf8'))
return result
def selectSql(self, database, sql, param, env):
login_result = sqlByIdb().login()
sql = sql.replace('%d', '%s')
for pa in param:
pa = "'" + str(pa) + "'"
sql = sql.replace('%s', pa, 1)
print(sql)
value = confOP().getYamlValue("idbSet")
if env == "on":
env = "live"
instance_id = value[database][env]
url = "http://docp.plt.babytree-inc.com/api/v1/sql/mysql/query/query/"
payload = json.dumps({
"instance_id": instance_id,
"db_name": database,
"tb_name": database,
"limit_num": 3000,
"sqlContent": sql
})
headers = {
'Authorization': login_result["sid"],
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
result = json.loads(response.text.encode('utf8'))
return result["results"][0]["rows"]
# -*- encoding=utf8 -*-
import pymysql
class delByBranchId(object):
def Delete_branch_by_id(self,id):
connection = pymysql.connect(host="10.17.65.108", user="root", password="Cmic.2023", database="spd3_herp_test2",
charset="utf8")
cursor = connection.cursor()
# 删除新增的院区数据,减少垃圾数据的产生,保证脚本下次还可以正常运行,接口脚本每次都使用新增数据
sql = "DELETE from mcms_branch_info where id = '%s';" % id
print(sql)
cursor.execute(sql)
cursor.execute("commit;")
print('%s院区数据已删除成功' % id)
cursor.close()
# delByBranchId().Delete_branch_by_name('11122222')
\ No newline at end of file
# -*- encoding=utf8 -*-
import pymysql
class delKindGoodsinfo(object):
def delKindGoodsinfo(self):
connection = pymysql.connect(host="10.17.65.108", user="root", password="Cmic.2023", database="spd3_herp_test2",
charset="utf8")
cursor = connection.cursor()
# 删除耗材分类下的产品,便于脚本下次执行时再次添加产品信息到该耗材分类中
sql = "DELETE from mcms_goods_kind_collection where kind_id=(select id from mcms_goods_kind where kind_name='9999_2');"
print(sql)
cursor.execute(sql)
cursor.execute("commit;")
print('耗材分类下的产品删除完毕' )
cursor.close()
def delkind(self):
connection = pymysql.connect(host="10.17.65.108", user="root", password="Cmic.2023", database="spd3_herp_test2",
charset="utf8")
cursor = connection.cursor()
# 删除耗材分类下的产品,便于脚本下次执行时再次添加产品信息到该耗材分类中
sql = "DELETE from mcms_goods_kind where kind_code in('9999','9999_2');"
print(sql)
cursor.execute(sql)
cursor.execute("commit;")
print('耗材分类删除完毕')
# delByBranchId().Delete_branch_by_name('11122222')
\ No newline at end of file
# -*- encoding=utf8 -*-
import pymysql
class delByNoticeName(object):
def delete_ByNoticeName(self):
connection = pymysql.connect(host="10.17.65.108", user="root", password="Cmic.2023", database="spd3_herp_test2",
charset="utf8")
cursor = connection.cursor()
# 删除新增的院区数据,减少垃圾数据的产生,保证脚本下次还可以正常运行,接口脚本每次都使用新增数据
sql = "update sys_notice set del_flag=1 where title like '%test%';"
print(sql)
cursor.execute(sql)
cursor.execute("commit;")
print('%s公告数据已逻辑删除成功')
cursor.close()
# delByNoticeName().delete_ByNoticeName()
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment