如何在Python中解析MySQL构建代码?

1 投票
3 回答
3002 浏览
提问于 2025-04-16 17:50

我把我的MySQL数据库导出了一个.txt/.sql文件(链接),想用这个文件在其他电脑上重建数据库。虽然在HeidiSQL中运行这个脚本没问题,但我想在启动我的应用程序之前,确保所有的表都存在并且是正确的。

我可以把导出的代码复制粘贴到我的Python代码里,但导出的内容是我数据库的直接表现,应该没有错误,而复制粘贴可能会出错……所以我尝试解析这个文件,但我的解析技能还需要提高。

这是代码的一部分:

CREATE TABLE IF NOT EXISTS `data` (
  `dataid` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `measurementid` int(10) unsigned NOT NULL DEFAULT '0',
  `frame` int(10) unsigned NOT NULL,
  `sensor_row` int(10) unsigned NOT NULL,
  `sensor_col` int(10) unsigned NOT NULL,
  `value` float unsigned NOT NULL,
  PRIMARY KEY (`dataid`),
  UNIQUE KEY `measurementid_frame_sensor_row_sensor_col` (`measurementid`,`frame`,`sensor_row`,`sensor_col`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

假设数据库data已经创建好了,我想找到一种方法来解析这些代码,如果需要的表不存在,就创建它们;如果有变化,就修改它们。

有没有什么建议可以帮助我解决这个问题?

3 个回答

1

只需要读取文件并执行里面的SQL语句就可以了。

我不太明白你还需要做什么。如果表已经存在,创建表的语句就不会执行。任何修改表的语句都会执行。

如果你需要把当前的数据库结构和你想更新的结构进行比较,这就比简单地“解析”文件要复杂得多。你可能需要使用某种迁移框架(我最喜欢的之一是Django的south)或者一个结构比较工具。

2

你可以试试这个叫做 sqlparse模块,它可以把一个文件里的内容拆分成一个个独立的SQL语句,然后你可以逐个执行这些语句。

你还可以用更高级的方式来处理SQL中的元素,比如 去掉所有的注释(除了函数内部的注释)。你可以用这种方法从创建表的语句中提取出表名,并检查这个表是否存在。

下面是一个拆分语句的例子:

import sqlparse

queries = '''
CREATE TABLE foo (id INTEGER);
CREATE TABLE bar (id INTEGER, name VARCHAR);
SELECT foo FROM bar WHERE id IN (1,2,3);
DELETE FROM bar WHERE id IN (3, 4);
-- a comment
DELETE FROM bar WHERE name IN ('chaos','atlas');
'''

for i, stmt, in enumerate(sqlparse.split(queries)):
    sql = stmt.strip()
    if not sql:
        continue
    print i, sql

输出结果:

0 CREATE TABLE foo (id INTEGER);
1 CREATE TABLE bar (id INTEGER, name VARCHAR);
2 SELECT foo FROM bar WHERE id IN (1,2,3);
3 DELETE FROM bar WHERE id IN (3, 4);
4 -- a comment
DELETE FROM bar WHERE name IN ('chaos','atlas');
3

你可以直接通过一个Python数据库适配器,从文件中完整地执行SQL语句:

import MySQLdb
sql_dump = open('builtcode.sql', 'r').read()

conn = MySQLdb.connect(db='soans', passwd='*****')
cur = conn.cursor()

cur.execute(sql_dump)

cur.connection.close()

结果是:

mysql> show tables;
+-----------------+
| Tables_in_soans |
+-----------------+
| anamnesis_main  |
| averagecontact  |

撰写回答