AttributeError:'sqlite3.Connection'对象属性'execute'是只读的

时间:2016-05-18 01:35:29

标签: python sqlite python-decorators

我尝试手动装饰sqlite3.Connection.execute但不允许。除了直接装饰sqlite3.Connection对象本身之外,还有其他方法吗?

我的代码:

    db = g._db = sqlite3.connect(app.config['DB_PATH'])

    def allow_direct_commit(f_execute):
        @functools.wraps(f_execute)
        def decorated(*args, **kwargs):
            r = f_execute(*args, **kwargs)
            r.commit = db.commit
            return r

        return decorated

    db.execute = allow_direct_commit(db.execute)

我的目标是能够做到:

 db.execute('whatever').commit()

如果我想代替:

db.execute('whatever')
db.commit()

注意:我正在使用Flask,而不是它应该对此示例有用。

编辑:事实证明,装饰sqlite3.Connection本身比我想象的更棘手,更糟糕。我还必须使用类似的黑客方法将commit设置为sqlite3.Cursor,并且还必须手动添加__iter__方法。我不知道为什么。我认为__getattribute__会采取这种做法,但我得到了TypeError: 'Cursor' object is not iterable。最后,遗憾的是,你不能functools.wraps一个班级。

如果有人能想出更好的版本,我会很高兴看到它。

    db  = sqlite3.connect(app.config['DB_PATH'])

    def allow_direct_commit(db):
        db_execute = db.execute

        @functools.wraps(db_execute)
        def decorated_execute(*args, **kwargs):
            r = db_execute(*args, **kwargs)

            class Cursor:
                def __getattribute__(self, attr):
                    if attr == 'commit':
                        return db.commit

                    return getattr(r, attr)

                def __iter__(self):
                    return r.__iter__()

            return Cursor()

        class DB:
            def __getattribute__(self, attr):
                if attr == 'execute':
                    return decorated_execute

                return getattr(db, attr)

        return DB()

    db = allow_direct_commit(db)

    g._db = db

0 个答案:

没有答案