1

I'm trying to use the Connection.set_authorizer method to only allow certain DB operations with a connection object. (The documentation is here)

I'm using this code to test:

import sqlite3 as sqlite

def select_authorizer(sqltype, arg1, arg2, dbname):  
    print("Test")  
    return sqlite.SQLITE_OK  #should allow all operations           

conn = sqlite.connect(":memory:")
conn.execute("CREATE TABLE A (name integer PRIMARY KEY AUTOINCREMENT)")
conn.set_authorizer(select_authorizer)
conn.execute("SELECT * FROM A").fetchall() #should still work

This gives me a sqlite3.DatabaseError: not authorized, without ever printing out "Test". I'm guessing I may have set up my authorizer wrong, and it's just failing to even call it. (Though the error message sure doesn't communicate that) But according to the documentation, this setup looks right.

EDIT: Changed sqlite.SQLITE_OKAY to sqlite.SQLITE_OK, but since the method doesn't seem to be called at all, not surprisingly that didn't help.

4

2 に答える 2

1

Martijn Pieter の答えは正しいです。その段落を読んだとき、どういうわけかその5番目の引数を見逃しました。

ドキュメントをより詳しく読んで、自分でこれを理解するのに本当に役立ったのは次の行です。sqlite.enable_callback_tracebacks(True)
この行により、コールバック関数内で発生したエラーのトレースバックが sqlite に出力されます。

于 2012-08-22T18:48:56.823 に答える
1

オーソライザーのコールバックは5 つの引数を取りますが、あなたのものは 4 つしか受け入れません:

コールバックの最初の引数は、承認される操作の種類を示します。2 番目と 3 番目の引数は、最初の引数に応じて引数または None になります。4 番目の引数は、該当する場合、データベースの名前 (「main」、「temp」など) です。5 番目の引数は、アクセス試行を担当する最も内側のトリガーまたはビューの名前です。このアクセス試行が入力 SQL コードから直接行われた場合は None です。

したがって、署名次のようになります。

def select_authorizer(sqltype, arg1, arg2, dbname, source):

一般に、そのようなコールバックをテストする場合、*argsワイルドカード パラメータを使用するとテストが簡単になります。

def select_authorizer(*args):
     print(args)
     return sqlite.SQLITE_OK

上記のコールバックは以下を出力します。

(21, None, None, None, None)
(20, 'A', 'name', 'main', None)

私があなたのテストを実行するときSELECT

SQLiteset_authorizerについてはC リファレンスを、使用されるさまざまな定数についてはアクション コード リファレンスを参照してください。

于 2012-08-22T08:04:14.127 に答える