pyodbcを使用してデータベースに接続するアプリケーションがあります。異なるdbエンジンで実行することができます。今私はそれをFirebirdに適応しようとします。私は結合parametres処理するためにネイティブpyodbcの方法を使用することができます(sqliteのでテスト、Sybaseの)いくつかのDBエンジンのためのpyodbcをFirebirdに接続してバインドするパラメータ
:
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)
:Oracleの場合
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)
は、私が実行されるように、いくつかの特別な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)
これは機能しません。今回のエラーはpyodbc.Error: ('HY000', '[HY000] [ODBC Firebird Driver][Firebird]Dynamic SQL Error\nSQL error code = -104\nToken unknown - line 1, column 5\nterm (-104) (SQLExecDirectW)')
です。
私はどんな解決策も探しているので、その2つの方法のいずれかで実行することができます。パフォーマンスの側面も非常に重要です。アプリケーションは頻繁には実行されませんが、コードの一部で約15万回挿入すると、files
テーブルに挿入されます。最初のエラーは、他の言葉で、あなたはFILE_TYPE_ID
と呼ばれるnot null
列にnull
値を挿入しているという事実によって引き起こされる
ここではFirebirdが実行しようとしている実際のSQLを見てみましょう。実際のSQLが 'pyodbc'から実行されているのを見る方法はありません。また、SQLとパラメータを渡すときにはそうしてはいけません。 Firebirdでクエリのログを有効にして、エラーの原因となったSQLを含めることができますか? – FlipperPA