Package: dbfaker
dbfaker介绍基于数据库层面批量生成有逻辑关联的数据软件架构对于要造大量数据来讲，有几种方式，一是通过开发写的接口来模拟真实用户场景来产生数据，这种方式在某些方面来讲是比较合适的，比如因为是模拟用户场景，业务数据完整，不会丢．但不好的地方就是要处理的地方太多，接口定义，签名，加密等等，还有扩展性也很不好，一个业务场景要写一套代码．另一种方式，是已知业务产生的数据之间的依赖关系后，直接在数据库中插入相关数据，本项目就是通过这种方式来实现，好处就是生成规则通过配置文件来描述即可（yaml文件），不需要额外添加代码（对于某些字段生成规则有可能需要单独编写方法），与测试库testrunner比较类似．现在已知有些库也支持直接在数据库内造数据，但对库表之间的关联关系的处理都做得不太好．另外对于测试人员进行自动化接口测试时，前置数据是个问题，是通过业务接口一条条跑完作为前置数据产生条件还是直接在数据库里面插入需要的数据呢？前面一种方式在业务场景复杂的时候用例的维护可能会变得极其麻烦。比如：你要测试一个用户加入商品到购物车的一个接口；前置数据有哪些？用户账号商品通过接口来造数据的流程如下：通过用户端注册接口来创建账号通过管理端接口登录，拿到token（预设管理端账号是已经存在了，如果不存在你还得注册管理端账号）登陆后通过管理端接口创建商品信息这三个步骤看起来简单，但实际上针对某些业务场景还有接口加密、签名、而且几乎每一条测试用例都需要用到N个前置条件，这些通过接口来调用的前置条件只要有一个失败就会影响你真正要测试的接口。做过接口测试的同学应该深有体会；实际上实现上述接口测试，真正要测的只是商品是否能正常加入到购物车；真正依赖的就只有两个数据，用户账号和商品信息。我们只需要在用户表和商品表里面各插入一条数据就可以了。通过本工具，只需要描述两个表的每个字段的生成规则就可以直接在数据库中插入两条“十分真实”的数据。用这种方式来解决测试用例前置条件的问题不说是最好的方式，但肯定是比上面的前置用例的方式好很多。本项目数据处理流程如下：安装gitclonehttps://gitee.com/guojongg/dbfaker.gitcddbfaker# 可先创建虚拟环境后再安装python3setup.pyinstall# 使用pip直接安装pip3installdbfaker# 卸载pipuninstalldbfaker使用说明１．　生成meta.yml文件，可通过内置工具table2yml.py来一键生成模板，生成后需完善模板中表字段的定义table2yml.py文件使用说明：usage:table2yml[-h][--connect[CONNECT]][--table_names[TABLE_NAMES]][--sql_file[SQL_FILE]][--output[OUTPUT]][--hide_command][type]数据库表转数据生成yaml文件格式工具

positionalarguments:type数据来源，table_name：通过输入表名与数据库链接方式，在数据库中获取数据库建表语句；table_statement:指定数据库建表语句的sql文件路径

optionalarguments:-h,--helpshowthishelpmessageandexit--connect[CONNECT]数据库连接语法，例如：mysql+mysqldb://user:password@host/dbname--table_names[TABLE_NAMES]数据库表，多个表以“,”分割--sql_file[SQL_FILE]数据库建表语句的sql文件路径--output[OUTPUT]输出文件名，默认为数据库表名+meta.yml--hide_comment不转换comment字段（可减少yml文件行数）使用举例1、在可以连接数据库的情况下直接指定数据库连接和要转换的表名来输出yaml文件table2ymltable_name--table_namesstu,course,choice_course--connectmysql+mysqldb://[dbuser]:[dbpassword]@[dbhost]/[dbname]--outputtest.yml2、在不能直接连接数据库，但有建表语句sql文件时可以通过下面的方法来输出yaml文件table2ymltable_statement--sql_filetest.sql--outputtest.yml2, 编辑meta.yml文件，文件格式如下package:-datetime#　导入额外的包，在jinja2模板中使用（下面有用到datetime包，所以要先导入）env:id:engine:faker.uuidtime_format:engine:faker.eq("%Y-%m-%d %H:%M:%S")tables:-table:stucomment:'学生表'columns:id:comment:数据主键idengine:eq('{{ env.id }}')# 通过引用环境变量中的值name:comment:姓名engine:nameidcard:comment:身份证号engine:ssnage:comment:年龄engine:eq('{{ datetime.datetime.now().year - int(stu.idcard[6:10]) }}')#　通过jinja２模板直接计算sex:comment:性别engine:faker.eq('{{ "man" if int(stu.idcard[-2]) % 2==1 else "female" }}')#　通过jinja２模板直接计算-table:coursecomment:'课程表'columns:id:comment:数据主键idengine:faker.uuidstu_id:comment:数据主键idengine:faker.eq('{{ stu.id }}')# 引用其他表中的值course_name:comment:课程名称engine:faker.choice(['数学','语文','英语','化学','地理'])# 通过内置方法从列表中随机取一个值course_time:comment:上课时间engine:faker.now(format="{{ env.time_format }}")# 通过内置方法获取当前时间，并按照指定格式返回extraction:stu_name:value:'{{stu.name}}'course_name:value:'{{course.course_name}}'３，创建ｓｑｌPC:~/01Work/07MyProject/dbfaker$sourcevenv/bin/activate(venv)PC:~/01Work/07MyProject/dbfaker$dbfaker-h
usage:dbfaker[-h][-n[NUMBER]][-i][-c[CONNECT]][-o[OUTPUT]][-p][--project_namePROJECT_NAME][meta_file]通过ｙｍｌ格式的描述文件来生成数据

positionalarguments:meta_fileyml文件所在路径

optionalarguments:-h,--helpshowthishelpmessageandexit-n[NUMBER],--number[NUMBER]生成数据数量-i,--insert是否插入到数据库-c[CONNECT],--connect[CONNECT]数据库连接语法，例如：mysql+mysqldb://pdmsadmin:system001@cpcs.homelabs.in/pdms_hospital-o[OUTPUT],--output[OUTPUT]指定文件名，输出内容到文件-p,--_print是否打印到控制台--project_namePROJECT_NAME初始化项目时的项目名称# 打印输出dbfakerdata/test.yml--number10-p# 保存到文件dbfakerdata/test.yml--number10-oout.sql# 插入到数据库dbfakerdata/test.yml--number10-i--connectmysql+mysqldb://pdmsadmin:system001@cpcs.homelabs.in/pdms_hospital通过上述模板文件生成出sql:(venv)guolong@guolong-PC:~/01Work/07MyProject/dbfaker$dbfakerdata/test.yml-p-n10100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████|10/10[00:00<00:00,121.26条/s]INSERTINTO`stu`(`id`,`name`,`idcard`,`age`,`sex`)VALUES('873ebda283ad418681427eee33599d88','常斌','320311197109145812','49','man');INSERTINTO`course`(`id`,`stu_id`,`course_name`,`course_time`)VALUES('c642936a6a3d4067a0bdeaa738e777f7','873ebda283ad418681427eee33599d88','英语','2020-10-21 16:39:07');INSERTINTO`stu`(`id`,`name`,`idcard`,`age`,`sex`)VALUES('975a595bdbe44bca9066e899cf095fdf','朱超','371403194412033153','76','man');INSERTINTO`course`(`id`,`stu_id`,`course_name`,`course_time`)VALUES('e7fce0bd705d407d82365c5078e18e9f','975a595bdbe44bca9066e899cf095fdf','语文','2020-10-21 16:39:07');INSERTINTO`stu`(`id`,`name`,`idcard`,`age`,`sex`)VALUES('c7a35fc6034b416b84633aba68f948a5','谭桂花','220881193603124667','84','female');INSERTINTO`course`(`id`,`stu_id`,`course_name`,`course_time`)VALUES('9ec067ab61384b82839f037d19046d54','c7a35fc6034b416b84633aba68f948a5','地理','2020-10-21 16:39:07');INSERTINTO`stu`(`id`,`name`,`idcard`,`age`,`sex`)VALUES('ec50b43857894724a8520fe4267cdb1c','黄颖','430424200102150376','19','man');INSERTINTO`course`(`id`,`stu_id`,`course_name`,`course_time`)VALUES('a82ca7d9dfb14084ac59f3eef81c397d','ec50b43857894724a8520fe4267cdb1c','语文','2020-10-21 16:39:07');INSERTINTO`stu`(`id`,`name`,`idcard`,`age`,`sex`)VALUES('ada7f3efbd6c44cbbb2b4e97f1e2192e','崔芳','110102197508318809','45','female');INSERTINTO`course`(`id`,`stu_id`,`course_name`,`course_time`)VALUES('09068ec48e344513aa13248afc2a6c9a','ada7f3efbd6c44cbbb2b4e97f1e2192e','语文','2020-10-21 16:39:07');INSERTINTO`stu`(`id`,`name`,`idcard`,`age`,`sex`)VALUES('c7be9316a52d4ce6813e2522c06ec244','伍建','530424195111204807','69','female');INSERTINTO`course`(`id`,`stu_id`,`course_name`,`course_time`)VALUES('b525533bd784470898075b6c3c98e319','c7be9316a52d4ce6813e2522c06ec244','化学','2020-10-21 16:39:07');INSERTINTO`stu`(`id`,`name`,`idcard`,`age`,`sex`)VALUES('ab8156d118ce47388ec080d4ca182324','张杰','430722199410179304','26','female');INSERTINTO`course`(`id`,`stu_id`,`course_name`,`course_time`)VALUES('df802e97f23e43c6b8329f3bc80532b4','ab8156d118ce47388ec080d4ca182324','化学','2020-10-21 16:39:07');INSERTINTO`stu`(`id`,`name`,`idcard`,`age`,`sex`)VALUES('dc508ae92cd14c2b8b44f881e9a2a9dc','温玲','361030193711149093','83','man');INSERTINTO`course`(`id`,`stu_id`,`course_name`,`course_time`)VALUES('37a72421f0ec419aa181cb38f3216866','dc508ae92cd14c2b8b44f881e9a2a9dc','语文','2020-10-21 16:39:07');INSERTINTO`stu`(`id`,`name`,`idcard`,`age`,`sex`)VALUES('48ddceaacddf43fd850a750c003f65e4','杨芳','530322197311251166','47','female');INSERTINTO`course`(`id`,`stu_id`,`course_name`,`course_time`)VALUES('083d692d6a35483a9f4c77d99cb74abc','48ddceaacddf43fd850a750c003f65e4','语文','2020-10-21 16:39:07');INSERTINTO`stu`(`id`,`name`,`idcard`,`age`,`sex`)VALUES('f1e6ff166e504f4b9a1c4ef5c2791e2d','万帅','321323197507311448','45','female');INSERTINTO`course`(`id`,`stu_id`,`course_name`,`course_time`)VALUES('47e6cbb2999c433fb15f2102eec95295','f1e6ff166e504f4b9a1c4ef5c2791e2d','地理','2020-10-21 16:39:07');执行完成，共生成10组数据更多例子usage example(使用举例)内置方法一览dbfaker内置方法速览自定义方法使用说明dbfaker自定义方法使用说明yaml文件版本转换说明yaml文件版本转换说明使用comment字段来描述生成规则使用comment字段来描述生成规则更新说明dbfaker更新说明觉得还可以，帮忙点个赞！！！如果有意见或建议或者遇到相关问题需要探讨解决方案欢迎给我提：Issue