db2text 0.1.17__tar.gz → 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. {db2text-0.1.17/db2text.egg-info → db2text-0.2.2}/PKG-INFO +4 -3
  2. {db2text-0.1.17 → db2text-0.2.2}/README.md +3 -2
  3. {db2text-0.1.17 → db2text-0.2.2}/database2text/datafile/dbtmanual.md +23 -7
  4. {db2text-0.1.17 → db2text-0.2.2}/database2text/datafile/dot.mb +8 -4
  5. db2text-0.1.17/database2text/datafile/sample/dbt_mysql.txt → db2text-0.2.2/database2text/datafile/sample/mysql/all.txt +12 -2
  6. {db2text-0.1.17 → db2text-0.2.2}/database2text/datafile/sample/opengauss/all.txt +9 -5
  7. {db2text-0.1.17 → db2text-0.2.2}/database2text/datafile/sample/oracle/all.txt +27 -0
  8. db2text-0.1.17/database2text/datafile/sample/dbt_mssql.txt → db2text-0.2.2/database2text/datafile/sample/sqlserver/all.txt +12 -3
  9. {db2text-0.1.17 → db2text-0.2.2}/database2text/mssql.py +7 -4
  10. {db2text-0.1.17 → db2text-0.2.2}/database2text/mysql.py +8 -6
  11. {db2text-0.1.17 → db2text-0.2.2}/database2text/opengauss.py +7 -1
  12. {db2text-0.1.17 → db2text-0.2.2}/database2text/oracle11.py +5 -2
  13. {db2text-0.1.17 → db2text-0.2.2}/database2text/tool.py +49 -9
  14. {db2text-0.1.17 → db2text-0.2.2/db2text.egg-info}/PKG-INFO +4 -3
  15. {db2text-0.1.17 → db2text-0.2.2}/db2text.egg-info/SOURCES.txt +2 -5
  16. {db2text-0.1.17 → db2text-0.2.2}/db2text.egg-info/entry_points.txt +1 -0
  17. {db2text-0.1.17 → db2text-0.2.2}/db2text.egg-info/requires.txt +1 -0
  18. {db2text-0.1.17 → db2text-0.2.2}/setup.py +3 -2
  19. db2text-0.1.17/database2text/datafile/sample/dbt_dot_mysql.txt +0 -16
  20. db2text-0.1.17/database2text/datafile/sample/dbt_dot_oracle.txt +0 -16
  21. db2text-0.1.17/database2text/datafile/sample/dbt_oracle11.txt +0 -30
  22. {db2text-0.1.17 → db2text-0.2.2}/LICENSE +0 -0
  23. {db2text-0.1.17 → db2text-0.2.2}/MANIFEST.in +0 -0
  24. {db2text-0.1.17 → db2text-0.2.2}/database2text/__init__.py +0 -0
  25. {db2text-0.1.17 → db2text-0.2.2}/database2text/datafile/sample/dbt_dot_mssql.txt +0 -0
  26. {db2text-0.1.17 → db2text-0.2.2}/database2text/dbt.py +0 -0
  27. {db2text-0.1.17 → db2text-0.2.2}/db2text.egg-info/dependency_links.txt +0 -0
  28. {db2text-0.1.17 → db2text-0.2.2}/db2text.egg-info/not-zip-safe +0 -0
  29. {db2text-0.1.17 → db2text-0.2.2}/db2text.egg-info/top_level.txt +0 -0
  30. {db2text-0.1.17 → db2text-0.2.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: db2text
3
- Version: 0.1.17
3
+ Version: 0.2.2
4
4
  Summary: database to text
5
5
  Home-page: https://gitee.com/chenc224/dbt
6
6
  Author: Chen chuan
@@ -30,7 +30,8 @@ License-File: LICENSE
30
30
 
31
31
  在命令行执行dbt即可。可以带参数指定命令文件,如果未指定,则使用当前目录下的dbt.txt文件。
32
32
 
33
- 详细的使用手册请参考
33
+ 如果dbt跟系统内其它软件冲突,可以使用db2text,效果是相同的。
34
34
 
35
- https://gitee.com/chenc224/dbt/blob/master/database2text/datafile/usermenual.md
35
+ 详细的使用手册请参考
36
36
 
37
+ https://gitee.com/chenc224/dbt/blob/master/database2text/datafile/dbtmanual.md
@@ -16,7 +16,8 @@
16
16
 
17
17
  在命令行执行dbt即可。可以带参数指定命令文件,如果未指定,则使用当前目录下的dbt.txt文件。
18
18
 
19
- 详细的使用手册请参考
19
+ 如果dbt跟系统内其它软件冲突,可以使用db2text,效果是相同的。
20
20
 
21
- https://gitee.com/chenc224/dbt/blob/master/database2text/datafile/usermenual.md
21
+ 详细的使用手册请参考
22
22
 
23
+ https://gitee.com/chenc224/dbt/blob/master/database2text/datafile/dbtmanual.md
@@ -12,9 +12,11 @@
12
12
  pip install db2text
13
13
  ```
14
14
 
15
- 执行代码为dbt,可以增加一个参数文件名作为执行文件,无参数则读取当前目录下的dbt.txt文件。
15
+ 执行命令为dbt,如果系统内原来有dbt命令,也可以使用db2text,这两个命令是完全等效的。
16
16
 
17
- 执行文件以.md结尾,则扫描.md文件中的配置信息,处理此md文件。
17
+ 可以增加一个参数文件名作为执行文件,无参数则读取当前目录下的dbt.txt文件。
18
+
19
+ 参数文件以.md结尾,则扫描.md文件中的配置信息,处理此md文件。
18
20
 
19
21
  # dbt.txt 配置文件格式
20
22
 
@@ -78,6 +80,8 @@ owner=属主 用于oracle等数据库需要读取的对象属主和连接数据
78
80
  ## render段
79
81
  file=文件名 行告诉执行器处理哪一个文件。
80
82
 
83
+ table= 可以设置只处理部分表,语法参考readdata段的内容。注意readdata段设置则在读入阶段就对表进行筛选,而在render段设置仅在输出时进行筛选。如果想提高处理速度,可以考虑在readdata段设置。如果是一次读入,然后分多次输出(比如输出到不同文件),则考虑在这里设置。
84
+
81
85
  help=y 会让执行器输出传递给jinja2渲染的数据内容,方便写模板时参考。
82
86
 
83
87
  start=和end=这两行告诉执行器在文件中搜索需要替换的文件内容的头和尾。头和尾可以是同一行,这样可以适应单行方式。搜索以python的re正则模块按行搜索。从文件头开始,搜索到start行之后继续搜索end,start和end以及中间的所有行就是找到的需要替换的文本块。
@@ -105,13 +109,24 @@ struct stru_{{ tname }} { //{{ tdesc }}
105
109
 
106
110
  生成dot语言(graphviz)的文件,显示表结构
107
111
 
108
- file=dot文件名
112
+ dotdir=指定dot文件目录,未指定则放在当前目录
113
+
114
+ pdfdir=指定pdf文件放在哪个目录,未指定则放在dotdir目录下
115
+
116
+ filename=dot和pdf文件名,不带扩展名
109
117
 
110
- cmd=neato -Tpdf test/kaoqin.dot -o test/kaoqin.pdf
118
+ dotcmd=neato 指定graphviz布局算法,可以选择twopi、circo、fdp和osage这些,未指定使用fdp。不建议使用dot,patchwork,布局严重有问题,也不建议使用neato、sfdp,生成的pdf尺寸有点问题。
111
119
 
112
- 生成dot文件后,执行cmd指定的命令,示例是生成pdf文件的命令格式。
120
+ page= 页名称列表,用空格隔开,如 用户类 权限相关 交易 流程控制等 other/其它
121
+
122
+ page设置的是页名称列表,每个页名称对应一个设置项,other或者其它不需要指定,会把没用过的表全部输出,每页设置如下:
123
+
124
+ 用户类=+ .*user.* 语法参照table=,
125
+
126
+ 每个页名称会生成一页pdf,最终合成得到一个多页的pdf。如果不需要多页pdf,可以不用设置page语句。
113
127
 
114
128
  ## end段
129
+
115
130
  发现这个段就意味着执行器停止扫描,这样可以把一些暂时不用的代码放在end段后面。
116
131
 
117
132
  这个段最好写上,因为执行器的“特性”,实际上它并不处理最后一个段。。。。
@@ -201,6 +216,7 @@ md列表,每一行是一个字典,代表一个字段,字典说明如下
201
216
  |desc|注释|
202
217
  |type|数据类型,原始数据库中的数据类型|
203
218
  |size|字段长度|
204
- |null|是否可为空|
219
+ |null|逻辑值,为真表示可为空|
205
220
  |default|默认值|
206
- |ts|类型+长度|
221
+ |ts|类型+长度,比如char(5)这样的格式|
222
+ |pk|逻辑值,为真表示是主键列|
@@ -1,18 +1,22 @@
1
1
  graph 表结构 {
2
- size = "8.268,11.693";
3
- # ratio="auto"
2
+ size = "8.5,11";
3
+ margin=0;
4
+ pad=0.1;
5
+ page="8.5,11";
6
+ # charset=utf8;
7
+ ratio="fill"
4
8
  # dpi = 300
5
9
  # rankdir = "TR"
6
10
  # node[shape=record fontname="wqy-zenhei" size="30,30"]
7
11
  node[shape=plaintext fontname="wqy-zenhei"]
8
12
 
9
- {% for t in exp.TABLE %}
13
+ {% for t in TABLE %}
10
14
  {{ t.tname }} [
11
15
  label=<
12
16
  <table border="1" cellborder="0">
13
17
  <tr><td colspan="3">{{ t.tdesc }} {{ t.tname }}</td></tr>
14
18
  {%- for c in t.md %}
15
- <tr><td align="left">{{ c.desc }}</td><td align="left">{{ c.name }}</td><td align="left">{{ c.ts }}</td></tr>
19
+ <tr><td align="left">{{ c.desc }}</td><td align="left">{{ c.pk and '<u>' or ''}}{{ c.name }}{{ c.pk and '</u>' or ''}}</td><td align="left">{{ c.ts }}</td></tr>
16
20
  {%- endfor %}
17
21
  </table>
18
22
  >
@@ -8,10 +8,13 @@ driver=mysql
8
8
  #database=库
9
9
  #port=3306
10
10
  #charset=utf8
11
- dbcfg=kaoqin
11
+ dbcfg=dbt_mysql
12
12
  :readdata
13
+ :export
14
+ #export段设置导出数据库里的相应内容为文本文件
15
+ datadir=test/mysql/export
13
16
  :render
14
- file=test/xxx.md
17
+ file=test/mysql/all.md
15
18
  help=n
16
19
  #table=tgroup tuser t_user_group t_app_group
17
20
  #使用help=y可以打印出传入模板的数据,方便写模板的时候使用
@@ -23,4 +26,11 @@ start=## {{ tname }}
23
26
  {% endfor %}
24
27
  end=
25
28
 
29
+ #根据模板生成dot文件,调用neato生成pdf文件
30
+ :dot
31
+ dotdir=test/mysql
32
+ pdfdir=local/mysql
33
+ filename=all
34
+ dotcmd=osage
35
+
26
36
  :end
@@ -5,10 +5,6 @@ code=utf8
5
5
  #冒号开头的行表示一段内容的开始,直到另外一个冒号或者是文件尾
6
6
  #执行时扫描配置文件,把每一段的内容传递给相应的处理函数处理
7
7
  :connect
8
- #connect段设置数据库类型以及连接所需要的数据,不同数据库需要的数据并不相同
9
- #loginname=loginname
10
- #password=password
11
- #dbserver=host address or ip or tnsname
12
8
  dbcfg=dbt_opengauss
13
9
  :readdata
14
10
  schema=dbt
@@ -20,7 +16,7 @@ datadir=test/opengauss/export
20
16
  file=test/opengauss/all.md
21
17
  help=n
22
18
  #使用help=y可以打印出传入模板的数据,方便写模板的时候使用
23
- #下面是模板样例,jinja2模板库,这个样例是根据表定义一个c语言的结构,用于pro*c使用
19
+ #下面是模板样例,jinja2模板库,这个样例是输出表定义到markdown文件中
24
20
  start=## {{ tname }}
25
21
  ## {{ tname }} {{ tdesc }}
26
22
  | 字段名 | 类型 | 长度 | 空 | 默认值 | 说明 |
@@ -28,4 +24,12 @@ start=## {{ tname }}
28
24
  {% for c in md %}| {{ c.name }} | {{ c.type }} | {{ c.size }} | {% if c.null == "Y" %}可{% endif %} | {{ c.default or "" }} | {{ c.desc }} |
29
25
  {% endfor %}
30
26
  end=
27
+
28
+ #根据模板生成dot文件,调用neato生成pdf文件
29
+ :dot
30
+ dotdir=test/opengauss
31
+ pdfdir=local/opengauss
32
+ filename=all
33
+ dotcmd=neato
34
+
31
35
  :end
@@ -10,10 +10,13 @@
10
10
  #password=password
11
11
  #dbserver=host address or ip or tnsname
12
12
  dbcfg=dbt_oracle
13
+
13
14
  :readdata
15
+
14
16
  :export
15
17
  #export段设置导出数据库里的相应内容为文本文件
16
18
  datadir=test/oracle/export
19
+
17
20
  :render
18
21
  file=test/oracle/all.md
19
22
  help=n
@@ -26,4 +29,28 @@ start=## {{ tname }}
26
29
  {% for c in ori %}| {{ c.COLUMN_NAME }} | {{ c.DATA_TYPE }} | {{ c.DATA_LENGTH }} | {% if c.NULLABLE == "Y" %}可{% endif %} | {{ c.DATA_DEFAULT or "" }} | {{ c.COLUMN_COMMENT }} |
27
30
  {% endfor %}
28
31
  end=
32
+
33
+ #根据模板生成dot文件,调用neato生成pdf文件
34
+ :dot
35
+ #cmd=neato -Tpdf test/oracle/all.dot -o local/oracle/alldot.pdf
36
+ dotdir=test/oracle
37
+ pdfdir=local/oracle
38
+ filename=all
39
+ dotcmd=neato
40
+ #可以选择dot,neato,twopi,circo,fdp,sfdp,patchwork和osage指定graphviz布局算法
41
+
42
+ #dot生成多页pdf的例子
43
+ :connect
44
+ dbcfg=lofta@ta
45
+ :readdata
46
+ table=ts.*
47
+ :dot
48
+ dotdir=test/oracle
49
+ pdfdir=local/oracle
50
+ filename=lofta
51
+ #dotcmd=fdp
52
+ page=份额类 other
53
+
54
+ 份额类=ts[a-f].*
55
+
29
56
  :end
@@ -3,15 +3,17 @@ code=gbk
3
3
  :connect
4
4
  driver=mssql
5
5
  #dbinfo={"server":"��������ַ","database":"����","user":"�û���","password":"����","port":1433,"readonly":true}
6
- dbcfg=ia_paladin
6
+ dbcfg=dbt_sqlserver
7
7
 
8
8
  :readdata
9
9
 
10
- help=y
10
+ #:export
11
+ #export�����õ������ݿ������Ӧ����Ϊ�ı��ļ�
12
+ #datadir=test/sqlserver/export
11
13
 
12
14
  :render
13
15
 
14
- file=test/ia.md
16
+ file=test/sqlserver/all.md
15
17
  help=n
16
18
  #ʹ��help=y���Դ�ӡ������ģ������ݣ�����дģ���ʱ��ʹ��
17
19
  #table=sw_program sw t_server
@@ -23,4 +25,11 @@ start=## {{ tname }}
23
25
  {% endfor %}
24
26
  end=
25
27
 
28
+ #����ģ������dot�ļ�������neato����pdf�ļ�
29
+ :dot
30
+ dotdir=test/sqlserver
31
+ pdfdir=local/sqlserver
32
+ filename=all
33
+ dotcmd=neato
34
+
26
35
  :end
@@ -11,7 +11,7 @@ class mssql(object):
11
11
  def ana_TABLE(otype):
12
12
  dbdata["sql"]["TABLE"]={}
13
13
  dbdata["exp"]["TABLE"]=[]
14
- sql="SELECT table_catalog,table_schema,table_name FROM INFORMATION_SCHEMA.TABLES where table_type='BASE TABLE'"
14
+ sql="SELECT table_catalog,table_schema,table_name FROM INFORMATION_SCHEMA.TABLES where table_type='BASE TABLE' order by 3"
15
15
  if 目录:
16
16
  sql=f"{sql} and table_catalog='{目录}'"
17
17
  if 集合:
@@ -21,6 +21,11 @@ class mssql(object):
21
21
  continue
22
22
  表id=db.res1(f"select object_id('{catalog}.{schema}.{表名}')")
23
23
  表注释=db.res1(f"select value from sys.extended_properties where major_id={表id} and class=1 and name='MS_Description'") or ""
24
+ 主键名=db.res1(f"SELECT k.CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS c JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS k ON c.CONSTRAINT_TYPE = 'PRIMARY KEY' AND c.CONSTRAINT_NAME = k.CONSTRAINT_NAME WHERE c.TABLE_NAME = '{表名}'")
25
+ 主键列=[]
26
+ if 主键名:
27
+ for pkcol, in db.exec(f"SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME = '{表名}' AND CONSTRAINT_NAME = '{主键名}'"):
28
+ 主键列.append(pkcol)
24
29
  原始信息=[]
25
30
  md=[]
26
31
  for i in db.exec2(f"select * from sys.columns where object_id={表id} order by column_id"):
@@ -33,7 +38,7 @@ class mssql(object):
33
38
  ts=f"{字段类型}({i['precision']})"
34
39
  else:
35
40
  ts=f"{字段类型}({i['precision']}.{i['scale']})"
36
- mddata={"name":i["name"], "desc":字段描述 or "", "type":字段类型, "size":i["max_length"], "null":i["is_nullable"], "default":"", "ts":ts}
41
+ mddata={"name":i["name"], "desc":字段描述 or "", "type":字段类型, "size":i["max_length"], "null":i["is_nullable"], "default":"", "ts":ts, "pk":i["name"] in 主键列}
37
42
  md.append(mddata)
38
43
  dbdata["sql"]["TABLE"][表名]=[] #暂不处理
39
44
  dbdata["exp"]["TABLE"].append({"tname":表名,"tdesc":表注释,"ori":原始信息,"c":[],"md":md})
@@ -60,5 +65,3 @@ def connect(arg):
60
65
  else:
61
66
  return dbtt.connect(arg,"pytds")
62
67
 
63
- def export(stdata,storidata):
64
- dbtt.export(stdata,storidata,dbdata)
@@ -7,7 +7,7 @@ from database2text.tool import *
7
7
 
8
8
  class mysql(object):
9
9
  def ana_TABLE(otype):
10
- for oname, in db.exec(f"select table_name from information_schema.tables where table_schema='{database}' and table_type='BASE TABLE'"):
10
+ for oname, in db.exec(f"select table_name from information_schema.tables where table_schema='{database}' and table_type='BASE TABLE' order by 1"):
11
11
  if 检查匹配(otype,oname):
12
12
  continue
13
13
  res=db.res1("show create table %s" %(oname))
@@ -15,13 +15,17 @@ class mysql(object):
15
15
  oridata=[]
16
16
  coldata=[]
17
17
  tdesc=db.res1("SELECT TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME ='%s' AND TABLE_SCHEMA = '%s'" %(oname,database))
18
- md=[] #markdown等用的字段数据,每字段一个字典
18
+ 主键列=[]
19
+ for pkcol, in db.exec(f"select column_name from information_schema.key_column_usage where TABLE_SCHEMA='{database}' and table_name='{oname}' and constraint_name='PRIMARY'"):
20
+ 主键列.append(pkcol)
21
+ md=[] #markdown用的字段数据,每字段一个字典
19
22
  for i in db.exec2("select * from information_schema.COLUMNS where TABLE_SCHEMA='%s' and table_name='%s' order by ORDINAL_POSITION" %(database,oname)):
20
23
  oridata.append(i)
21
- mddata={"name":i["COLUMN_NAME"], "desc":i["COLUMN_COMMENT"], "type":i["DATA_TYPE"], "size":i["CHARACTER_OCTET_LENGTH"], "null":i["IS_NULLABLE"]=="NO", "default":i["COLUMN_DEFAULT"], "ts":i["COLUMN_TYPE"]}
24
+ mddata={"name":i["COLUMN_NAME"], "desc":i["COLUMN_COMMENT"], "type":i["DATA_TYPE"], "size":i["CHARACTER_OCTET_LENGTH"], "null":i["IS_NULLABLE"]=="NO", "default":i["COLUMN_DEFAULT"], "ts":i["COLUMN_TYPE"], "pk":i["COLUMN_NAME"] in 主键列}
22
25
  md.append(mddata)
23
26
  dbdata["sql"]["TABLE"][oname]=odata
24
27
  dbdata["exp"]["TABLE"].append({"tname":oname,"tdesc":tdesc,"ori":oridata,"c":coldata,"md":md})
28
+
25
29
  def ana_VIEW(otype):
26
30
  for oname, in db.exec(f"select table_name from information_schema.tables where table_schema='{database}' and table_type='VIEW'"):
27
31
  oridata=[]
@@ -33,6 +37,7 @@ class mysql(object):
33
37
  mddata={"name":i["COLUMN_NAME"], "desc":i["COLUMN_COMMENT"], "type":i["DATA_TYPE"], "size":i["CHARACTER_OCTET_LENGTH"], "null":i["IS_NULLABLE"]=="NO", "default":i["COLUMN_DEFAULT"], "ts":i["COLUMN_TYPE"]}
34
38
  md.append(mddata)
35
39
  dbdata["exp"]["TABLE"].append({"tname":oname,"tdesc":tdesc,"ori":oridata,"c":coldata,"md":md})
40
+
36
41
  def getobjtext(otype,oname):
37
42
  _,ssql=db.res1("show create %s %s" %(otype,oname))
38
43
  return ssql
@@ -58,7 +63,4 @@ def connect(arg):
58
63
  db.conn=pymysql.connect(**stdata)
59
64
  database=db.res1("select database()")
60
65
 
61
- def export(stdata,storidata):
62
- dbtt.export(stdata,storidata,dbdata)
63
-
64
66
  __all__=[]
@@ -9,12 +9,16 @@ from database2text.tool import *
9
9
 
10
10
  class opengauss(object):
11
11
  def ana_TABLE(otype):
12
- for 表id,表名 in db.exec(f"select oid,relname from pg_class where relkind='r' and relnamespace=(select oid from pg_namespace where nspname='{stdata['schema']}')"):
12
+ for 表id,表名 in db.exec(f"select oid,relname from pg_class where relkind='r' and relnamespace=(select oid from pg_namespace where nspname='{stdata['schema']}') order by oid"):
13
13
  odata=db.res1(f"select pg_get_tabledef({表id})")
14
14
  oridata=[]
15
15
  coldata=[]
16
16
  tdesc=db.res1(f"select description from pg_description where objoid={表id} and objsubid=0")
17
17
  md=[] #markdown等用的字段数据,每字段一个字典
18
+ 主键列=[]
19
+ 主键名=db.res1(f"select constraint_name from information_schema.table_constraints where table_schema='{stdata['schema']}' and table_name='{表名}' and constraint_type = 'PRIMARY KEY'")
20
+ for pkcol, in db.exec(f"select column_name from information_schema.key_column_usage where TABLE_SCHEMA='{stdata['schema']}' and table_name='{表名}' and constraint_name='{主键名}'"):
21
+ 主键列.append(pkcol)
18
22
  for i in db.exec2(f"select * from pg_attribute where attrelid={表id} and attnum>0 and not attisdropped order by attnum"):
19
23
  oridata.append(i)
20
24
  if i["atttypid"] not in 字段类型:
@@ -25,6 +29,8 @@ class opengauss(object):
25
29
  if i["attlen"]<0:
26
30
  mddata["size"]=字符长度 or 数字长度
27
31
  mddata["default"]=默认 or ""
32
+ mddata["ts"]=f"{mddata['type']}({mddata['size']})"
33
+ mddata["pk"]=i["attname"] in 主键列
28
34
  md.append(mddata)
29
35
  dbdata["sql"]["TABLE"][表名]=odata
30
36
  dbdata["exp"]["TABLE"].append({"tname":表名,"tdesc":tdesc,"ori":oridata,"c":coldata,"md":md})
@@ -7,7 +7,7 @@ from database2text.tool import *
7
7
 
8
8
  class oracle(object):
9
9
  def ana_TABLE(otype):
10
- for oname, in db.exec("select object_name from all_objects where object_type=:ot and owner=:owner",ot=otype,owner=owner):
10
+ for oname, in db.exec("select object_name from all_objects where object_type=:ot and owner=:owner order by 1",ot=otype,owner=owner):
11
11
  if 检查匹配(otype,oname):
12
12
  continue
13
13
  if oname.startswith("SYS_EXPORT_TABLE"):
@@ -91,7 +91,10 @@ class oracle(object):
91
91
  if data_type in ("VARCHAR2","VARCHAR","CHAR","NVARCHAR2","NVARCHAR") and char_length==1:
92
92
  cns=column_name
93
93
  coldata.append({"type":ctype,"name":column_name,"ns":cns,"ns2":cns2,"desc":desc})
94
- md.append({"name":column_name,"desc":desc,"type":data_type,"size":char_length,"null":nullable=="N","default":data_default,"ts":ts})
94
+ 主键列=[]
95
+ for pkcol, in db.exec(f"SELECT cols.column_name FROM user_constraints cons, user_cons_columns cols WHERE cons.constraint_type = 'P' AND cons.constraint_name = cols.constraint_name AND cons.owner = cols.owner and cons.owner = '{owner}' AND cols.table_name = '{oname}'"):
96
+ 主键列.append(pkcol)
97
+ md.append({"name":column_name,"desc":desc,"type":data_type,"size":char_length, "null":nullable=="N", "default":data_default,"ts":ts, "pk":column_name in 主键列})
95
98
  odata=odata[:-2]
96
99
  odata=odata+"\n);"
97
100
  dbdata["sql"]["TABLE"][oname]=odata
@@ -118,17 +118,54 @@ class dot(object):
118
118
  def __init__(self,arg):
119
119
  模板文件=pathlib.Path.joinpath(pathlib.Path(__file__).parent,"datafile","dot.mb")
120
120
  模板=open(模板文件,encoding="utf8").read()
121
- f=open(arg["file"],"wt",encoding="utf8")
122
- f.write(jinja2.Template(模板).render(dbdata))
123
- f.close()
124
- if "cmd" in arg:
125
- print(arg["cmd"])
126
- os.system(arg["cmd"])
121
+ 分页数据=[]
122
+ for page in arg.get("page","如果没有设置page就搞一个默认的").split():
123
+ if page in ["other","其它","其他"]:
124
+ if arg.get(page,"输出剩下的所有表") not in 分页数据:
125
+ 分页数据.append(arg.get(page,"输出剩下的所有表"))
126
+ elif page in arg:
127
+ if arg[page] not in 分页数据:
128
+ 分页数据.append(arg[page])
129
+ 文件序号=0
130
+ 已经使用=set()
131
+ dot列表=[]
132
+ pdf列表=[]
133
+ for 分页 in 分页数据:
134
+ 文件序号=文件序号+1
135
+ dotname=os.path.join(arg.get("dotdir","."),f"{arg['filename']}_{文件序号}.dot")
136
+ data={"TABLE":[]}
137
+ for t in dbdata["exp"]["TABLE"]:
138
+ if 分页=="输出剩下的所有表":
139
+ if t["tname"] not in 已经使用:
140
+ data["TABLE"].append(t)
141
+ else:
142
+ if not 检查匹配(分页,t["tname"]):
143
+ data["TABLE"].append(t)
144
+ 已经使用.add(t['tname'])
145
+ if len(data["TABLE"])>0: #确实有数据
146
+ fdot=open(dotname,"wt",encoding="utf8")
147
+ fdot.write(jinja2.Template(模板).render(data))
148
+ fdot.close()
149
+ dot列表.append(dotname)
150
+ pdfname=os.path.join(arg.get("pdfdir","."),f"{arg['filename']}_{文件序号}.pdf")
151
+ pdf列表.append(pdfname)
152
+ cmd='%s -Tpdf %s -o %s' %(arg.get("dotcmd","fdp"),dotname,pdfname)
153
+ print(cmd)
154
+ os.system(cmd)
155
+ if len(pdf列表)>0:
156
+ import PyPDF3
157
+ pdfout=PyPDF3.PdfFileMerger()
158
+ for i in pdf列表:
159
+ pdf=PyPDF3.PdfFileReader(i)
160
+ pdfout.append(pdf)
161
+ pdfname=os.path.join(arg.get("pdfdir","."),f"{arg['filename']}.pdf")
162
+ with open(pdfname,"wb") as fout:
163
+ pdfout.write(fout)
127
164
 
128
165
  class render(object):
129
166
  def __init__(self,arg):
130
167
  for t in dbdata["exp"]["TABLE"]:
131
- if not "table" in stdata or t["tname"].lower() in stdata["table"].split():
168
+ if not 检查匹配("TABLE",t["tname"]):
132
169
  self.rendertable(t)
133
170
  def rendertable(self,t):
134
171
  if "help" in stdata and stdata["help"].lower() in ["y","1"]:
@@ -195,11 +232,14 @@ def connect(arg,mname):
195
232
  db.conn=m.connect(**dbarg)
196
233
  return db.conn
197
234
 
198
- def 检查匹配(类型,名称):
235
+ def 检查匹配(类型或者筛选值,名称):
199
236
  '根据stdata[类型]确定名称是否需要处理'
237
+ if type(名称)!=type(""):return True #仅处理字符串
200
238
  排除标志=True
201
239
  加减="+"
202
- for i in stdata.get(类型.lower(),"+ .*").split():
240
+ if 类型或者筛选值.lower() in ["table","view"]:
241
+ 类型或者筛选值=stdata.get(类型或者筛选值.lower(),"+ .*")
242
+ for i in 类型或者筛选值.split():
203
243
  if i in ["+","-"]:
204
244
  加减=i
205
245
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: db2text
3
- Version: 0.1.17
3
+ Version: 0.2.2
4
4
  Summary: database to text
5
5
  Home-page: https://gitee.com/chenc224/dbt
6
6
  Author: Chen chuan
@@ -30,7 +30,8 @@ License-File: LICENSE
30
30
 
31
31
  在命令行执行dbt即可。可以带参数指定命令文件,如果未指定,则使用当前目录下的dbt.txt文件。
32
32
 
33
- 详细的使用手册请参考
33
+ 如果dbt跟系统内其它软件冲突,可以使用db2text,效果是相同的。
34
34
 
35
- https://gitee.com/chenc224/dbt/blob/master/database2text/datafile/usermenual.md
35
+ 详细的使用手册请参考
36
36
 
37
+ https://gitee.com/chenc224/dbt/blob/master/database2text/datafile/dbtmanual.md
@@ -12,13 +12,10 @@ database2text/tool.py
12
12
  database2text/datafile/dbtmanual.md
13
13
  database2text/datafile/dot.mb
14
14
  database2text/datafile/sample/dbt_dot_mssql.txt
15
- database2text/datafile/sample/dbt_dot_mysql.txt
16
- database2text/datafile/sample/dbt_dot_oracle.txt
17
- database2text/datafile/sample/dbt_mssql.txt
18
- database2text/datafile/sample/dbt_mysql.txt
19
- database2text/datafile/sample/dbt_oracle11.txt
15
+ database2text/datafile/sample/mysql/all.txt
20
16
  database2text/datafile/sample/opengauss/all.txt
21
17
  database2text/datafile/sample/oracle/all.txt
18
+ database2text/datafile/sample/sqlserver/all.txt
22
19
  db2text.egg-info/PKG-INFO
23
20
  db2text.egg-info/SOURCES.txt
24
21
  db2text.egg-info/dependency_links.txt
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
+ db2text = database2text.dbt:main
2
3
  dbt = database2text.dbt:main
@@ -1,2 +1,3 @@
1
+ PyPDF3
1
2
  dbcfg
2
3
  jinja2
@@ -8,7 +8,7 @@ with open("README.md", "r",encoding='utf-8') as fh:
8
8
 
9
9
  setuptools.setup(
10
10
  name="db2text",
11
- version="0.1.17",
11
+ version="0.2.2",
12
12
  author="Chen chuan",
13
13
  author_email="kcchen@139.com",
14
14
  description="database to text",
@@ -23,7 +23,7 @@ setuptools.setup(
23
23
  ],
24
24
  python_requires='>=3.5',
25
25
  install_requires=[
26
- 'jinja2','dbcfg'
26
+ 'jinja2','dbcfg','PyPDF3'
27
27
  ],
28
28
  # scripts=["bin/dbt"],
29
29
  zip_safe= False,
@@ -31,6 +31,7 @@ setuptools.setup(
31
31
  entry_points={
32
32
  'console_scripts': [
33
33
  'dbt=database2text.dbt:main',
34
+ 'db2text=database2text.dbt:main',
34
35
  ],
35
36
  },
36
37
  )
@@ -1,16 +0,0 @@
1
- #生成dot文件,用于griphviz
2
-
3
- #以下部分是mysql数据库
4
- :connect
5
-
6
- dbcfg=kaoqin
7
-
8
- :readdata
9
-
10
- table= + .* - auth.* nav.* django.*
11
-
12
- :dot
13
- file=test/kaoqin.dot
14
- cmd=neato -Tpdf test/kaoqin.dot -o test/kaoqin.pdf
15
-
16
- :end
@@ -1,16 +0,0 @@
1
- #生成dot文件,用于griphviz
2
-
3
- #以下部分是oracle数据库
4
- :connect
5
-
6
- dbcfg=xtjk@cc
7
-
8
- :readdata
9
-
10
- table= + .* - auth.* nav.* django.*
11
-
12
- :dot
13
- file=test/xtjk.dot
14
- cmd=neato -Tpdf test/xtjk.dot -o test/xtjk.pdf
15
-
16
- :end
@@ -1,30 +0,0 @@
1
- #sample for oracle 11
2
- #oracle11的样例文件
3
- #号开头的行为注释,并不需要处理
4
- #冒号开头的行表示一段内容的开始,直到另外一个冒号或者是文件尾
5
- #执行时扫描配置文件,把每一段的内容传递给相应的处理函数处理
6
- :connect
7
- #connect段设置数据库类型以及连接所需要的数据,不同数据库需要的数据并不相同
8
- #loginname=loginname
9
- #password=password
10
- #dbserver=host address or ip or tnsname
11
- dbcfg=xtjk@cc
12
- :readdata
13
- table= + .* - sw.* auth.* \
14
- table= nav
15
- :export
16
- #export段设置导出数据库里的相应内容为文本文件
17
- datadir=test/xtjk
18
- :render
19
- file=test/xtjk.md
20
- help=n
21
- #使用help=y可以打印出传入模板的数据,方便写模板的时候使用
22
- #下面是模板样例,jinja2模板库,这个样例是根据表定义一个c语言的结构,用于pro*c使用
23
- start=## {{ tname }}
24
- ## {{ tname }} {{ tdesc }}
25
- | 字段名 | 类型 | 长度 | 空 | 默认值 | 说明 |
26
- | :---- | :---- | ----: | :---- | :---- | :---- |
27
- {% for c in ori %}| {{ c.COLUMN_NAME }} | {{ c.DATA_TYPE }} | {{ c.DATA_LENGTH }} | {% if c.NULLABLE == "Y" %}可{% endif %} | {{ c.DATA_DEFAULT or "" }} | {{ c.COLUMN_COMMENT }} |
28
- {% endfor %}
29
- end=
30
- :end
File without changes
File without changes
File without changes
File without changes