python - 读取 .sql 文件以在 Python 中执行 (pymysql)

标签 python mysql pymysql

我正在尝试创建一个多脚本工具,它将接受一个 .sql 文件的参数并执行它。

我已经设置了一个简单的测试,只在一个数据库上执行,但是语法每次都会给我带来问题。

DELIMITER $$
CREATE DEFINER=`a_user`@`%` PROCEDURE `a_procedure`(
    IN DirectEmployeeID TEXT,
    IN StartRange DATE,
    IN EndRange DATE
)
BEGIN
SELECT aColumn
WHERE thisThing = 1;
END$$
DELIMITER ;

明确地说,这个脚本已经过测试,并且在通过时可以正常工作:

mysql -uuser -p -hhost -Pport databaseName < file.sql

也可以通过 mysql workbench 工作。

我在另一个网站上看到了这种解决方案:

with conn.cursor() as cursor:
    f = sys.argv[1]
    file = open(f, 'r')
    sql = " ".join(file.readlines())
    cursor.execute(sql)

这给了我一个 MySQL 语法错误:

pymysql.err.ProgrammingError: (1064, u"You have an error in your SQL syntax; 
check the manual that corresponds to your MySQL server version for the right 
syntax to use near 'DELIMITER $$\n CREATE DEFINER=`a_user`@`%` PROCEDURE 
`MyCommissionsDirect`(\n \tIN ' at line 1")

如您所见,mysql 不喜欢脚本中的换行符。

然后我尝试了这个:

with conn.cursor() as cursor:
    f = sys.argv[1]
    file = open(f, 'r')
    sql = ''
    line = file.readline()
    while line:
        sql += ' ' + line.strip('\n').strip('\t')
        line = file.readline()
    print sql
    cursor.execute(sql)

还有另一个语法问题,打印显示这是一行,这在 mysqlworkbench 中不起作用。甚至不尝试执行它,这很奇怪。

当我先将 DELIMETER $$ 放在单独的一行时,它会在 mysqlworkbench 中执行。

在这种情况下,我觉得我可能会让事情变得越来越复杂。我很惊讶 pymysql 没有直接执行 sql 文件的方法。我厌倦了尝试进行字符串操作并让它为这个特定文件工作,因为那样的话,让这个工具变得模棱两可和可重用的梦想就破灭了。

我是否以完全错误的方式处理此问题?

谢谢!

最佳答案

这是我使用 SQL 文件和 PyMySQL 的解决方案。这些文件包含许多以 ; 结尾的请求,用于拆分列表中的请求。因此,请注意列表中缺少的 ;

我决定添加缺少的 ; 不在函数中以保留 for 循环。也许有更好的方法。

创建-db-loff.sql:

DROP DATABASE IF EXISTS loff;
CREATE DATABASE loff CHARACTER SET 'utf8';
USE loff;

CREATE TABLE product(
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `code` BIGINT UNSIGNED NOT NULL UNIQUE,
    `name` VARCHAR(200),
    `nutrition_grades` VARCHAR(1)
);

CREATE TABLE category(
    `id`INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR(200)
);

CREATE TABLE asso_prod_cat(
    `category_id` INT UNSIGNED NOT NULL,
    `product_id` INT UNSIGNED NOT NULL,
    CONSTRAINT `fk_asso_prod_cat_category`
        FOREIGN KEY(category_id)
        REFERENCES category(id)
        ON DELETE CASCADE,
    CONSTRAINT `fk_asso_prod_cat_product`
        FOREIGN KEY(product_id)
        REFERENCES product(id)
        ON DELETE CASCADE
);

db.py :

DB_CONFIG = {
    'host': 'localhost',
    'user': 'loff',
    'pass': 'loff',
    'db': 'loff',
    'char': 'utf8',
    'file': 'create-db-loff.sql'
}

def get_sql_from_file(filename=DB_CONFIG['file']):
    """
    Get the SQL instruction from a file

    :return: a list of each SQL query whithout the trailing ";"
    """
    from os import path

    # File did not exists
    if path.isfile(filename) is False:
        print("File load error : {}".format(filename))
        return False

    else:
        with open(filename, "r") as sql_file:
            # Split file in list
            ret = sql_file.read().split(';')
            # drop last empty entry
            ret.pop()
            return ret

request_list = self.get_sql_from_file()

if request_list is not False:

    for idx, sql_request in enumerate(request_list):
        self.message = self.MSG['request'].format(idx, sql_request)
        cursor.execute(sql_request + ';')

关于python - 读取 .sql 文件以在 Python 中执行 (pymysql),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36946444/

相关文章:

php - 特定和广泛的 MySQL 搜索

python - 类型错误:在字符串格式化期间、将数据上传到 Web sql 服务器期间,并非所有参数都被转换,

python - f 字符串中的整数表示类型不返回预期格式

python - datetime.strptime 和 dateutil 解析之间的区别?

python - 带有键值(不是路径)的 SSHTunnel

python - Selenium 和 Python — 如何在延迟加载网页中等待元素附加到父级?

mysql - 搜索多个表

php - 从两个表中获取数据并将它们收集到数组中并计算一个表结果的行数

mysql - 使用 PyMySQL 时语法无效

python - 如何将变量传递给 MySQL 的 LIMIT 子句?