gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 08:10:14 43 4
gpt4 key购买 nike

我正在尝试创建一个多脚本工具,它将接受一个 .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/

43 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com