FirebirdSQL に対して SQLAlchemy をinsert
実行しています。プロジェクトでコマンドを実行すると、SQLAlchemy は接続に対する実行から戻るときに例外を発生させます。ただし、insert
クエリは正常に作成および実行されています。データベースにクエリを実行すると、アイテムが実際に正しく挿入されていることがわかります。
編集:fbcore.py
私は今、モジュールを掘り下げて、値をチェックして、主キー ID を生成するために使用される項目がそのデータを返す方法が問題であることを示していvalue
ます。はですが、実際の値は です は、主キーを自動インクリメントするために作成したシーケンス ジェネレーターによって返される値です (例: )。これは、それを修正することで問題を解決する必要があることを示唆していますが、その方法はわかりません。ジェネレーターはデータベース内では正しく動作しているように見えますが、SQLAlchemy に戻すと問題が発生します。vartype
SEQUENCE
vartype
SQL_LONG
[<an integer>]
<an integer>
[14]
詳細については、既存の実装とスタック トレースについては以下を参照してください。
私のコード:
class Project:
# (I've snipped project instantiation, where engine connection, table, etc. are configured)
def save_project(self, id_=None, title=None, file_name=None, file_location=None):
# Build the dictionary of values to store
values = {}
if title is not None:
values['title'] = title
if file_name is not None:
values['file_name'] = file_name
if file_location is not None:
values['file_location'] = file_location
# Simplification: I account for the case that there *is* data---skipping that here
# Execute the correct kind of statement: insert or settings_update.
if id_ is None:
statement = self.table.insert()
else:
statement = self.table.update().where(self.table.c.id == id_)
result = self.connection.execute(statement, values)
# If we inserted a row, get the new primary key. Otherwise, return
# the one specified by the user; it does not change on settings_update.
project_id = result.inserted_primary_key if result.is_insert else id_
トレースバック:
File "/Users/chris/development/quest/workspace/my_project/data/tables.py", line 350, in save_project
result = self.connection.execute(statement, values)
File "/Users/chris/.virtualenvs/my_project/lib/python3.3/site-packages/sqlalchemy/engine/base.py", line 720, in execute
return meth(self, multiparams, params)
File "/Users/chris/.virtualenvs/my_project/lib/python3.3/site-packages/sqlalchemy/sql/elements.py", line 317, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "/Users/chris/.virtualenvs/my_project/lib/python3.3/site-packages/sqlalchemy/engine/base.py", line 817, in _execute_clauseelement
compiled_sql, distilled_params
File "/Users/chris/.virtualenvs/my_project/lib/python3.3/site-packages/sqlalchemy/engine/base.py", line 947, in _execute_context
context)
File "/Users/chris/.virtualenvs/my_project/lib/python3.3/site-packages/sqlalchemy/engine/base.py", line 1111, in _handle_dbapi_exception
util.reraise(*exc_info)
File "/Users/chris/.virtualenvs/my_project/lib/python3.3/site-packages/sqlalchemy/util/compat.py", line 168, in reraise
raise value
File "/Users/chris/.virtualenvs/my_project/lib/python3.3/site-packages/sqlalchemy/engine/base.py", line 940, in _execute_context
context)
File "/Users/chris/.virtualenvs/my_project/lib/python3.3/site-packages/sqlalchemy/dialects/firebird/kinterbasdb.py", line 106, in do_execute
cursor.execute(statement, parameters or [])
File "/Users/chris/.virtualenvs/my_project/lib/python3.3/site-packages/fdb/fbcore.py", line 3323, in execute
self._ps._execute(parameters)
File "/Users/chris/.virtualenvs/my_project/lib/python3.3/site-packages/fdb/fbcore.py", line 2991, in _execute
self.__Tuple2XSQLDA(self._in_sqlda, parameters)
File "/Users/chris/.virtualenvs/my_project/lib/python3.3/site-packages/fdb/fbcore.py", line 2782, in __Tuple2XSQLDA
sqlvar.sqlscale)
File "/Users/chris/.virtualenvs/my_project/lib/python3.3/site-packages/fdb/fbcore.py", line 2266, in _check_integer_range
if (value < vmin) or (value > vmax):
TypeError: unorderable types: list() < int()
なぜこれが問題なのかを理解するには、SQLAlchemy についてまだ十分に理解していません。私のステートメントのスタイルは、チュートリアルのスタイルとほとんど同じです。これは、パラメータが渡される方法に問題があるようです。おそらく、キーワード引数ではなく dict を使用することに関するものでしょうか? しかし、ここで何か問題があることを示唆するパラメーターの処理方法に関するドキュメントには何もありません。私が見ているものからは正しいようです。
また、用語をメソッドにself.table.insert().values(values)
渡すのではなく、これを試してみましたが、同じ結果が得られました(予想どおり)。values
execute
編集:メソッドに渡されたパラメーターがリストまたはタプルとして指定されていない場合、TypeError が発生するという点でexecute
、docstring を読んだことに注意してください。fbcore.py
これはドキュメントにまだ反映されていない変更ですか?
編集 2:コメントにあるように、スタック トレースは、 fdb を使用して実行するようにエンジンを明示的に構成しましたが、kinterbasdb ドライバーに対して実行されていることを示しています。これも私を混乱させます。