利用python解决mysql视图导入导出依赖的问题

视图

视图是一个虚拟表(非真实存在),其本质是根据SQL语句获取动态的数据集,并为其命名,用户使用时只需使用名称即可获取结果集,并可以将其当作表来使用。

创建视图

创建一个名称为v1的视图,其功能就是查询color表中的所有数据

CREATE VIEW v1 AS SELECT * FROM color;

查看视图

使用视图时,将其当作表进行操作即可,由于视图是虚拟表,所以无法使用其对真实表进行创建、更新和删除操作,仅能做查询用。

select * from v1; -- 等于执行SELECT * FROM color

输出结果

+-----+--------+
| nid | title |
+-----+--------+
| 1 | red |
| 2 | yellow |
+-----+--------+
2 rows in set (0.00 sec)

修改视图

ALTER VIEW v1 AS SELECT * FROM color WHERE nid = 1;

删除视图

DROP VIEW v1;

引用

navicat是mysql可视化工具中最棒的,但是,在处理视图的导入导出方面,它是按照视图名称的字母顺序来处理的,若视图存在依赖,在导入过程中就会报错。这个问题一直困绕我,一度因为我使用docker来部署mysql而绕过了这个问题。最近不得不直面这个问题,因此,写了一个小工具来解决它。

整体思路

在mysql很容易查出所有视图和其定义,因此可以写一个视图导出工具,存储时对各视图的保存位置进行调整,处理好它们之间的依赖关系,被依赖的放前面,这样就解决了导入时的依赖问题。

获取视图信息

运行以下查询语句,就能获得该数据库中所有视图的信息。

select * from information_schema.VIEWS where TABLE_SCHEMA = DatabaseName

查询结果字段说明:

  • TABLE_NAME : 数所库中视图名称
  • VIEW_DEFINITION : 视图的定义代码,只有查询语句部分
  • DEFINER : 视图定义(建立)者名称
  • SECURITY : 安全级别

总之,所有视图的信息都在这个表中保存,我要完成任务,只需要TABLE_NAME和VIEW_DEFINITION就可以了。

算法描述

  • 将查询结果放到dict中,视图名称为key;视图定义为value;
  • 编写处理依赖关系的函数process_rely,输入参数中的rely_old为保存所有视图名称的数组;返回参数为按依赖关系调整顺序后的视图名称数组。之所以这样做,是一开始考虑到,依赖关系复杂时,可能一次迭代处理不好,需要递归调用或多次调用。

process_rely函数算法描述:

第一层循环,从rely_old中取一个视图名称

第二层循环,从dict中取出一个键值

若键值被第一层元素的定义所依赖

若键值还不在结果数组中

若第一层元素不在结果数组中

追加键值到结果数组中

第一层元素在结果数组中

将键值插入到第一层元素前

键值在结果数组中

第一层元素在结果数组中

查找各自在结果数组中的位置

若第一层元素在键值的后

将键值移动到第一层元素前

第二层循环结束时,若第一层元素还不在结果集中

将第一层元素追加到结果集中

返回结果集

上面的说明,是按python代码模式给出的。很幸运,算法一次就能将复杂的依赖关系处理好了。我在编写的过程中,刚开始依赖算法不完善时,通过多次迭代也能处理好复杂的依赖关系。因此,坚定了必胜的信心,完成了这个任务。

完整代码

import pymysql
conn = pymysql.connect(host='172.17.0.1', port=3306, user='root',
      passwd='123456', db='database', charset='utf8mb4')
def process_rely(parmas={}, rely_old=[]):
 _rely = []
 _keys = list(parmas.keys())
 for k in rely_old:
  for bl in _keys:
   if str(parmas[k]).find(bl) > -1:
    if bl not in _rely:
     if k not in _rely:
      _rely.append(bl)
     else:
      i = _rely.index(k)
      _rely.insert(i, bl)
    else:
     if k in _rely:
      i = _rely.index(k)
      j = _rely.index(bl)
      if i < j:
       del _rely[j]
       _rely.insert(i, bl)
  if k not in _rely:
   _rely.append(k)
 return _rely
cur = conn.cursor()
cur.execute('select TABLE_NAME, VIEW_DEFINITION from information_schema.VIEWS where TABLE_SCHEMA = %s ', 'database')
rs = cur.fetchall()
cur.close()
conn.close()
ps = {}
for al in rs:
 ps['`' + al[0] + '`'] = al[1]
rely = process_rely(ps, list(ps.keys()))
# rely = process_rely(ps, rely1)
file_object = open('view.sql', 'w')
for al in rely:
 file_object.write('DROP VIEW IF EXISTS ' + al + ';\n')
 file_object.write('CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW ' + al +
      ' AS ' + ps[al] + ';\n\n')
file_object.close()

小结

思路要清晰,代码要一步步的向最终目标靠近,积跬步以至千里。在做这个工具时,一开始觉得很麻烦,依赖关系若是深层次的,可能一次处理不好,正因为采用的迭代的思想,最后才完成了一次迭代解决问题的完美结局。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • Python实现 多进程导入CSV数据到 MySQL

    前段时间帮同事处理了一个把 CSV 数据导入到 MySQL 的需求.两个很大的 CSV 文件, 分别有 3GB.2100 万条记录和 7GB.3500 万条记录.对于这个量级的数据,用简单的单进程/单线程导入 会耗时很久,最终用了多进程的方式来实现.具体过程不赘述,记录一下几个要点: 批量插入而不是逐条插入 为了加快插入速度,先不要建索引 生产者和消费者模型,主进程读文件,多个 worker 进程执行插入 注意控制 worker 的数量,避免对 MySQL 造成太大的压力 注意处理脏数据导致的异

  • Python导入txt数据到mysql的方法

    本文实例讲述了Python导入txt数据到mysql的方法.分享给大家供大家参考.具体分析如下: 从TXT文本转换数据到MYSQL数据库,接触一段时间python了 第一次写东西 用的是Python2.7 #!/usr/bin/python #coding=utf-8 import _mysql,sys,io def addCity(prov,city,tel,post): try: conn=_mysql.connect("192.168.1.99",'php','php'); co

  • python批量导出导入MySQL用户的方法

    数据库迁移(A -> B),需要把用户也迁移过去,而用户表(mysql.user)有上百个用户.有2种方法进行快速迁移:1,在同版本的条件下,直接备份A服务器的mysql数据库,还原到B服务器.2,要是不同版本的数据(5.1 -> 5.5),很可能mysql数据库下面的一些表结构,甚至表数据的默认值都不一样,按照1的方法进行迁移,虽然最后也是可以正常访问,但是还是有些不太放心,很可能会影响到了B服务器上的MySQL,这样就需要用命令行来生成帐号了,这样是最安全和放心的.下面用python脚本来

  • Python使用MYSQLDB实现从数据库中导出XML文件的方法

    本文实例讲述了Python使用MYSQLDB实现从数据库中导出XML文件的方法.分享给大家供大家参考.具体分析如下: 这里需要给前端以xml格式提供一些数据,这些数据在目前的数据库中已经存在. 如果使用django返回xml数据的话,需要包装下头信息: 复制代码 代码如下: r = HttpResponse(str_xml) r.mimetype = "text/xml" r['Content-Type'] = "application/xml" 另外,使用grou

  • 利用python解决mysql视图导入导出依赖的问题

    视图 视图是一个虚拟表(非真实存在),其本质是根据SQL语句获取动态的数据集,并为其命名,用户使用时只需使用名称即可获取结果集,并可以将其当作表来使用. 创建视图 创建一个名称为v1的视图,其功能就是查询color表中的所有数据 CREATE VIEW v1 AS SELECT * FROM color; 查看视图 使用视图时,将其当作表进行操作即可,由于视图是虚拟表,所以无法使用其对真实表进行创建.更新和删除操作,仅能做查询用. select * from v1; -- 等于执行SELECT

  • Python之csv文件从MySQL数据库导入导出的方法

    Python从MySQL数据库中导出csv文件处理 csv文件导入MySQL数据库 import pymysql import csv import codecs def get_conn(): conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='root', db='test_csv', charset='utf8') return conn def insert(cur, sql, args): c

  • MySQL数据库导入导出数据之报错解答实例讲解

    导出数据 报错 SHOW VARIABLES LIKE "secure_file_priv"; 查看默认导出目录 mysql> SELECT * FROM student INTO OUTFILE "G:\ProgramData\MySQL\MySQL Server 8.0\Uploads\student.txt"; ERROR 1290 (HY000): The MySQL server is running with the --secure-file-p

  • python 解决mysql where in 对列表(list,,array)问题

    例如有这么一个查询语句: select * from server where ip in (....) 同时一个存放ip 的列表 :['1.1.1.1','2.2.2.2','2.2.2.2'] 我们希望在查询语句的in中放入这个Ip列表,这里我们首先会想到的是用join来对这个列表处理成一个字符串,如下: >>> a=['1.1.1.1','2.2.2.2','2.2.2.2'] >>> ','.join(a) '1.1.1.1,2.2.2.2,2.2.2.2' 可

  • 利用python对mysql表做全局模糊搜索并分页实例

    在写django项目的时候,有的数据没有使用模型管理(数据表是动态添加的),所以要直接使用mysql.前端请求数据的时候可能会指定这几个参数:要请求的页号,页大小,以及检索条件. """ tableName: 表名 pageNum: 请求的页的编号 pageSize: 每一页的大小 searchInfo: 需要全局查询的信息 """ def getMysqlData(tableName, pageNum, pageSize, searchInfo

  • 如何利用Python连接MySQL数据库实现数据储存

    目录 介绍 Python连接MySQL实现数据储存 总结 介绍 MySQL是一个关系型数据库,MySQL由于性能高.成本低.可靠性好,已经成为最流行的开源数据库.最开始由瑞典的MySQL AB公司开发,后来被甲骨文公司(Oracle)收购. 如何利用Python连接MySQL数据库实现数据储存,下面我们将着重介绍. Python连接MySQL实现数据储存 首先我们需要准备Python的pymysql模块,MySQL数据库(这个自行网上找教学安装),Navicat Premium 15数据库工具(

  • 利用Python绘制MySQL数据图实现数据可视化

    本教程的所有Python代码可以在网上的IPython notebook中获取. 考虑在公司里使用Plotly?可以看一下Plotly的on-premises企业版.(注:On-premises是指软件运行在工作场所或公司内部,详见维基百科) 注意操作系统:尽管Windows或Mac用户也可以跟随本文操作,但本文假定你使用的是Ubuntu系统(Ubuntu桌面版或Ubuntu服务器版).如果你没有Ubuntu Server,你可以通过Amazon的Web服务建立一个云平台(阅读这份教程的前半部分

  • MYSQL 数据库导入导出命令

    MySQL命令行导出数据库 1,进入MySQL目录下的bin文件夹:cd MySQL中到bin文件夹的目录 如我输入的命令行:cd C:\Program Files\MySQL\MySQL Server 4.1\bin (或者直接将windows的环境变量path中添加该目录) 2,导出数据库:mysqldump -u 用户名 -p 数据库名 > 导出的文件名 如我输入的命令行:mysqldump -u root -p news > news.sql   (输入后会让你输入进入MySQL的密码

  • mysql导入导出数据中文乱码解决方法小结

    linux系统中 linux默认的是utf8编码,而windows是gbk编码,所以会出现上面的乱码问题. 解决mysql导入导出数据乱码问题 首先要做的是要确定你导出数据的编码格式,使用mysqldump的时候需要加上--default-character-set=utf8, 例如下面的代码: 复制代码 代码如下: mysqldump -uroot -p --default-character-set=utf8 dbname tablename > bak.sql 那么导入数据的时候也要使用-

  • SQL Server导入导出数据时最常见的一个错误解决方法

    现在建站主要使用的还是ASP与PHP,这两种语言一般使用的数据库分别为SQL Server和mysql,这两种数据库各有各长处,也说不上谁好谁坏,看个人习惯了. SQL Server 导入和导出向导的作用是将数据从源复制到目标.该向导还可以为您创建目标数据库和目标表.但是,如果必须复制多个数据库或表,或者必须复制其他类型的数据库对象,则应改用复制数据库向导. 在数据库导入导出时总失败,错误信息如下: 复制代码 代码如下: 正在验证 (错误) 消息 错误 0xc0202049: 数据流任务 1:

随机推荐