sqlite3 set_authorizer方法有问题

时间:2012-08-22 07:05:30

标签: python sqlite

我尝试使用Connection.set_authorizer方法仅允许某些带有连接对象的数据库操作。 (文档为here

我正在使用此代码进行测试:

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

这给了我一个sqlite3.DatabaseError: not authorized,没有打印出来"测试"。我猜我可能设置了我的授权人错误,而且它甚至都没有调用它。 (虽然错误消息肯定没有通信)但是根据文档,这个设置看起来正确。

编辑:将sqlite.SQLITE_OKAY更改为sqlite.SQLITE_OK,但由于该方法似乎根本没有被调用,因此毫无疑问没有帮助。

2 个答案:

答案 0 :(得分:1)

授权者回调需要 5 个参数,但你的只接受四个:

  

回调的第一个参数表示要授权的操作类型。第二个和第三个参数将是参数或None,具体取决于第一个参数。第四个参数是数据库的名称(“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时。

有关使用的各种常量,请参阅C reference for SQLite set_authorizeraction codes reference

答案 1 :(得分:1)

Martijn Pieter的回答是正确的;当我读到那段时,我不知何故错过了第五个论点。

我还发现,通过文档更仔细阅读的内容真正帮助我解决了这个问题:sqlite.enable_callback_tracebacks(True)
此行将导致sqlite为回调函数中发生的错误打印回溯。