使用pyodbc绑定参数并连接到Firebird

问题描述 投票:1回答:1

我有一个使用pyodbc连接到数据库的应用程序。它可以通过不同的数据库引擎运行。现在我尝试将它改编为Firebird。

对于一些数据库引擎(使用sqlite,Sybase测试),我可以使用本机pyodbc方式来处理绑定参数:

cnxn = pyodbc.connect(connect_string, autocommit=True)
cur = cnxn.cursor()
cur.execute("insert into files (file_type_id, path, md5) values (?, ?, ?)", file_type_id, path, md5)

对于Oracle,我必须准备一些特殊的SQL来运行:

cnxn = pyodbc.connect(connect_string, autocommit=True)
cur = cnxn.cursor()
sql = """DECLARE v_file_type_id INT; v_path varchar2(1024); v_md5 varchar2(32);
         BEGIN
         v_file_type_id := %d;
         v_path := '%s';
         v_md5 := '%s';
         insert into files (file_type_id, path, md5) values (v_file_type_id, v_path, v_md5);
         END;""" % (file_type_id, path, md5)
cur.execute(sql)

第一种方法不适用于Firebird。我收到错误:pyodbc.IntegrityError: ('23000', '[23000] [ODBC Firebird Driver][Firebird]validation error for column FILE_TYPE_ID, value "*** null ***" (-625) (SQLExecDirectW)')

我尝试准备专用的SQL,就像Oracle一样,但我遇到了一些问题。

cnxn = pyodbc.connect(connect_string, autocommit=True)
cur = cnxn.cursor()
sql = """set term ^ ;
         execute block
         as
         declare v_file_type_id int = %d;
         declare v_path varchar(1024) = '%s';
         declare v_md5 varchar(32) = '%s';
         begin
         insert into files (file_type_id, path, md5) values (:v_file_type_id, :v_path, :v_md5);
         end
         ^
         set term ; ^""" % (file_type_id, path, md5)
cur.execute(sql)

它不起作用。这次的错误是:qazxsw poi。

我正在寻找任何溶剂,所以我将能够以任何两种方式运行它。性能方面也很重要 - 应用程序不经常运行,但每次代码部分都会向pyodbc.Error: ('HY000', '[HY000] [ODBC Firebird Driver][Firebird]Dynamic SQL Error\nSQL error code = -104\nToken unknown - line 1, column 5\nterm (-104) (SQLExecDirectW)')表插入约50k。

python firebird pyodbc
1个回答
2
投票

第一个错误是由于您将files值插入名为nullnot null列,换句话说您的变量FILE_TYPE_ID为null,并且列上的约束不允许这样做,或者其他内容出错。

我用Python或其DB-API做了一段时间已经有一段时间了,但据我记忆,你执行的方式是错误的:

file_type_id

应该(注意使用元组)

cur.execute("insert into files (file_type_id, path, md5) values (?, ?, ?)", file_type_id, path, md5)

第二个错误是由cur.execute("insert into files (file_type_id, path, md5) values (?, ?, ?)", (file_type_id, path, md5)) 不是有效的Firebird SQL语句引起的,它是特定于客户端工具切换语句终止符的语句,另请参见set term

Execute block是一个匿名的“存储”过程,通常不用于以这种方式执行预准备语句。由于使用了字符串格式,因此使用执行块特别不安全,因为你使用了字符串格式,而且由于执行块,这种形式比执行'normal'语句更危险。

有几个用于Python,firebird procedural query throwing "token unknown" error at "SET TERM #;"FDB的Firebird数据库驱动程序,这样您就不需要使用ODBC。

© www.soinside.com 2019 - 2024. All rights reserved.