python读取数据库准备性能测试账号数据

本文介绍了一段Python脚本,用于根据SQLServer数据生成适用于LoadRunner的参数化dat文件。脚本通过多行SQL语句、参数化查询、文件操作及编码设置,实现了按比例分配不同部门的账号数据,有效简化了测试准备工作。

       做一个系统的测试,需要根据总测试人数按比例准备各个部门的测试的账号,其中的账号数据都从SQL Server中读取。为了简化工作,制作了一个python脚本。可以生成LoadRunner参数化中使用的dat数据文件。


1、由于SQL Server语句十分长,可以使用三个双引号的方式将多行文本括起来,其中如where id='0102'中'0102'这样的运算符后面的数可以参数化,用“?”表示,然后列出参数表,如:
cursor.execute("""
               select user_id, user_name
                 from users
                where last_logon < ?
                  and bill_overdue = ?
               """, '2001-01-01', 'y')

2、python从数据库中读出的数据最终是要写入.dat文件中的,文件操作函数与txt函数的操作一样,只不过open处改了后缀。(写入方式的不同:‘w’会覆盖之前的内容,‘a’不覆盖之前写好的内容,继续在后面添加)
由于LoadRunner会将数据的第一行看做是名称,因此在读取数据库中数据前,应当先写入一行名字行。
LoadRunner能读的逗号是英文的半角
f=open(r'd://550.dat','w')
f.write('StuffCode'+','+'loginID'+','+'NickName'+'\n')

3、要注意,写入时需要使用gbk编码,LoadRunner读入dat后缀文件时,只能正确读入gbk编码方式的文本,如果不加干涉直接输出,那么生成的dat文件在loadrunner中看,就会发现中文都被显示为乱码了,解决方法就是在输出中文时在后面再用函数encode进行gbk编码
在python中写入SQL语言由于每个部门的人数不同,因此希望select top x,x希望是一个变量,遗憾的是,python无法将这样的值用参数代替,因此我只能曲折的使用了fetchmany(x),同样成功取出结果中的前x个数

results=cur.fetchmany(num)

for r in results:
f.write(r[0]+','+r[1]+','+r[2].encode('gbk')+'\n')

4、如果不在最开始对python的数据编码方式进行转换,那么会报以下错误
UnicodeEncodeError: 'ascii' codec can't encode characters in position 47-48: ordinal not in range(128)
在读入文件前要加入
import sys
reload(sys)
sys.setdefaultencoding( "utf-8" )
print sys.getdefaultencoding()


5、按比例分配就存在“总数*百分比”这样的计算,结果是一个浮点数,但我需要取出的是一个含义为“人的个数”的值,因此需要强制转换为整数值,表达式前加入int即可:“int(总数*百分比)”
因为在求取部门人数比例的时候会遇到计算部门人数/总人数,这个结果是一个小于1的数,所以python对两个整数的“/”计算结果为0。解决方法就是在定义部门人数的数组时,直接定义为浮点数,即129.00,python自带的sum()函数就可以对浮点数求和了。将各部门人数装在一个数组中,p=[123.00,124.00,12.00],sum(p)即可
讲一个插曲:平时用LoadRunner是用的C编程,看到求和直觉反应就在python里面敲如
for i in range(0,3):
    sum+=p[i]
这样写python会提示只有整数相加才能这么用的。实际在python中,语法的使用更加灵活,平时在C编程环境中习惯了,有时反而会误导自己,当然,深究起来,还是python学得不扎实,所以会想不到去用自带函数。



附完整代码:
import  pyodbc
import sys
reload(sys)
sys.setdefaultencoding( "utf-8" )
print sys.getdefaultencoding()

PEOPLE=550 ##总人数,每次测试时不同
f=open(r'd://test.dat','w')
f.write('StuffCode'+','+'loginID'+','+'NickName'+'\n') ##LoadRunner默认标题行
q=['020','030','040','130','140','901','902','903','104'] ##部门编号
p=[133.00,29.00,49.00,17.00,14.00,179.00,170.00,168.00,68.00] ##部门人数
test=PEOPLE*1.2 ##账号留出20%的余量
print test

cnxn=pyodbc.connect("DRIVER={SQL SERVER};SERVER=[IP];DATABASE=[数据库名];UID=[账号];PWD=[密码]")
cur=cnxn.cursor()

for i in range(0,9):
num=int(test*(p[i]/sum(p)))
cur.execute("""select B.AccountId,A.LoginId,A.NickName , C.deptcode from Account as A
left join AccountOfDepartment as B on A.Id=B.AccountId
left join Departments as C on B.DepartId=C.Id
where Password like '0000'
and A.RecordState = 2
and C.DeptCode like ?
order by DeptCode,LoginId""",
q[i])
print (num)
print q[i]

results=cur.fetchmany(num)
for r in results:
f.write(r[0]+','+r[1]+','+r[2].encode('gbk')+'\n')

f.close()
cur.close()
cnxn.close()

这样每次修改一下PEOPLE总人数,运行一下就可以做出一个用LoadRunner测试时用的账号数据了。
<think>我们被要求实现Python实时检测数据库数据变化的功能。根据引用[2],Python提供了多种方法来实现实时监测数据库数据变化。常见的数据库如MySQL、PostgreSQL等,我们可以利用它们的特性或外部工具来实现。方法一:使用数据库的binlog(MySQL)对于MySQL,我们可以通过监听binlog来获取数据变化。binlog是MySQL的二进制日志,记录了所有对数据库的修改操作。我们可以使用Python库`python-mysql-replication`来读取binlog。步骤:1.确保MySQL开启了binlog,并且配置为ROW模式(这样才能获取到每一行改变的具体数据)。2.使用`pipinstallmysql-replication`安装库。3.编写代码连接MySQL,并指定要监听的binlog文件和位置(或者从当前开始监听)。示例代码:```pythonfrompymysqlreplicationimportBinLogStreamReader#配置MySQL连接信息MYSQL_SETTINGS={"host":"localhost","port":3306,"user":"root","passwd":"yourpassword"}#创建BinLogStreamReader实例stream=BinLogStreamReader(connection_settings=MYSQL_SETTINGS,server_id=100,#唯一ID,用于标识这个客户端blocking=True,#阻塞等待新事件resume_stream=True,#从上次断开的位置继续only_events=[DeleteRowsEvent,WriteRowsEvent,UpdateRowsEvent]#只监听增删改事件)forbinlogeventinstream:forrowinbinlogevent.rows:event={"schema":binlogevent.schema,"table":binlogevent.table}ifisinstance(binlogevent,DeleteRowsEvent):event["action"]="delete"event["data"]=row["values"]elifisinstance(binlogevent,UpdateRowsEvent):event["action"]="update"event["data"]=row["after_values"]#修改后的数据event["old_data"]=row["before_values"]#修改前的数据elifisinstance(binlogevent,WriteRowsEvent):event["action"]="insert"event["data"]=row["values"]print(event)stream.close()```方法二:使用触发器+消息队列另一种方法是在数据库中使用触发器,当数据变化时,触发器将变化写入一个中间表或发送消息到消息队列(如RabbitMQ、Kafka),然后Python程序监听消息队列。但是,这种方法需要修改数据库结构(添加触发器),并且可能对数据库性能有影响。方法三:轮询(Polling)如果不要求严格实时,可以采用轮询的方式,定期查询数据库并比较结果。但这种方法效率较低,且实时性差。方法四:使用PostgreSQL的LISTEN/NOTIFY如果使用PostgreSQL,可以利用其内置的LISTEN/NOTIFY机制。当数据变化时,触发器可以发送通知,Python程序通过监听通道获取通知。示例:1.在PostgreSQL中创建触发器函数,在增删改时执行NOTIFY。2.在Python中使用psycopg2监听通知。代码示例:```pythonimportpsycopg2conn=psycopg2.connect("dbname='mydb'user='postgres'host='localhost'password='password'")conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)cur=conn.cursor()cur.execute("LISTENtest_channel;")whileTrue:conn.poll()whileconn.notifies:notify=conn.notifies.pop(0)print("GotNOTIFY:",notify.pid,notify.channel,notify.payload)```方法五:使用第三方工具(如Maxwell、Debezium)如引用[3]提到,可以使用Maxwell实时抓取MySQL的binlog并生成JSON消息,然后发送到Kafka等消息队列,Python程序消费Kafka消息即可。步骤:1.部署并配置Maxwell,连接到MySQL并指定输出(如Kafka)。2.Python使用kafka消费者接收消息。总结:根据数据库类型和具体需求选择合适的方法。对于MySQL,推荐使用binlog监听或Maxwell等工具;对于PostgreSQL,推荐使用LISTEN/NOTIFY。注意:实时监听数据库变化通常用于数据同步、实时分析等场景,但要注意对数据库性能的影响。相关问题:1.如何确保实时监听数据库变化时的性能?2.除了上述方法,还有哪些技术可以实现数据库的实时监控?3.在分布式数据库环境中如何实现数据变化监听?</think>### Python实现数据库数据实时监控与变化检测 要实现Python实时监控数据库数据变化,主要有以下4种方法,根据数据库类型和需求选择合适方案: #### 方法1:基于数据库日志(推荐MySQL方案) **原理**:通过解析MySQL的binlog日志捕获数据变更事件 ```python # 安装依赖:pip install mysql-replication from pymysqlreplication import BinLogStreamReader # 配置数据库连接 mysql_settings = { "host": "localhost", "port": 3306, "user": "monitor_user", "passwd": "your_password" } stream = BinLogStreamReader( connection_settings=mysql_settings, server_id=100, # 唯一客户端ID blocking=True, # 实时阻塞模式 resume_stream=True, # 断点续传 only_events=["WriteRowsEvent", "UpdateRowsEvent", "DeleteRowsEvent"] ) for event in stream: print(f"变更类型: {type(event).__name__}") print(f"数据库: {event.schema} 表: {event.table}") for row in event.rows: if isinstance(event, DeleteRowsEvent): print(f"删除数据: {row['values']}") elif isinstance(event, UpdateRowsEvent): print(f"更新前: {row['before_values']} -> 更新后: {row['after_values']}") else: print(f"新增数据: {row['values']}") stream.close() ``` **配置要求**: 1. 启用MySQL binlog:在`my.cnf`添加: ```ini [mysqld] server-id=1 log-bin=mysql-bin binlog_format=ROW # 必须为ROW模式 ``` 2. 创建监控用户: ```sql CREATE USER 'monitor_user'@'%' IDENTIFIED BY 'password'; GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'monitor_user'@'%'; ``` #### 方法2:基于时间戳轮询(通用方案) **原理**:定期检查最后更新时间字段 ```python import time import pymysql def monitor_table_changes(): conn = pymysql.connect(host='localhost', user='user', password='pass', db='db') last_max_id = 0 last_update = None while True: with conn.cursor() as cursor: # 查询新增/修改记录 cursor.execute(""" SELECT id, data, update_time FROM target_table WHERE id > %s OR update_time > %s ORDER BY update_time ASC """, (last_max_id, last_update or '1970-01-01')) results = cursor.fetchall() if results: for row in results: print(f"变更记录: ID={row[0]}, 数据={row[1]}, 时间={row[2]}") last_max_id = max(last_max_id, row[0]) last_update = row[2] if row[2] > last_update else last_update time.sleep(5) # 5秒轮询间隔 monitor_table_changes() ``` **要求**:表需包含`id`自增列和`update_time`时间戳字段 #### 方法3:使用变更数据捕获(CDC)工具 **推荐工具**:Maxwell + Kafka(引用[3]方案) ```mermaid graph LR MySQL[MySQL binlog] --> Maxwell Maxwell -->|JSON格式| Kafka[Kafka Topic] Kafka --> Python[Python消费者] ``` **Python消费者示例**: ```python from kafka import KafkaConsumer consumer = KafkaConsumer( 'maxwell_topic', bootstrap_servers=['localhost:9092'], auto_offset_reset='earliest' ) for msg in consumer: change_data = json.loads(msg.value) print(f"操作类型: {change_data['type']}") print(f"数据变更: {change_data['data']}") ``` #### 方法4:数据库特定功能(PostgreSQL方案) **利用PostgreSQL的LISTEN/NOTIFY**: ```python import psycopg2 conn = psycopg2.connect("dbname=mydb user=postgres") conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) cur = conn.cursor() cur.execute("LISTEN data_change;") while True: conn.poll() while conn.notifies: notify = conn.notifies.pop(0) print(f"收到变更通知: {notify.payload}") ``` ### 关键注意事项 1. **性能影响**:binlog方案对数据库性能影响最小(约3-5%),轮询方案在高频时影响较大[^4] 2. **数据一致性**:binlog和CDC工具可保证不丢失变更事件 3. **安全配置**: - 使用只读账号 - 网络隔离 - 加密传输 4. **异常处理**:需实现重连机制和异常日志 ### 方案选择建议 | 场景 | 推荐方案 | 时延 | 复杂度 | |------|----------|------|--------| | MySQL实时同步 | binlog监听 | < 1s | ★★★☆ | | 跨数据库通用 | 时间戳轮询 | 轮询间隔 | ★★☆☆ | | 大数据管道 | Maxwell+Kafka | < 500ms | ★★★★ | | PostgreSQL | LISTEN/NOTIFY | < 100ms | ★★☆☆ | > 实际项目中推荐采用binlog方案(MySQL)或Maxwell工具链,它们提供可靠的低延迟变更捕获能力[^2]。 --- ### 相关问题 1. 如何区分数据库数据插入、更新和删除操作? 2. 当监控多张表的数据变化时,应该如何优化架构设计? 3. 在高并发场景下,如何保证数据变更事件的顺序性? 4. 除了数据库本身,是否可以通过应用层事件来实现数据变化监控? 5. 如何实现对NoSQL数据库(如MongoDB)的实时数据监控?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值