Декоратор для бд Python

Функция по работе с бд:

def select_all():
    conn = sqlite3.connect("db.sqlite")
    cur = conn.cursor()
    data = cur.execute("SELECT * FROM product").fetchall()
    cur.close()
    conn.close()
    return data

Таких и функций очень много. Как можно сделать декоратор что бы код стал короче и не писать постоянно

conn = sqlite3.connect("db.sqlite")
cur = conn.cursor()
cur.close()
conn.close()

А было что то типо такого:

@my_deco
def select_all():
    data = cur.execute("SELECT * FROM product").fetchall()
    return data

Про ORM системы знаю, но в этом проекте ими запретили пользоваться


Ответы (1 шт):

Автор решения: CrazyElf

А где вы возьмёте cur, если будете использовать декоратор? Если у вас запросы однотипные, то декоратор в общем-то и не нужен, достаточно сделать функцию:

def sql_execute(sql):
    conn = sqlite3.connect("db.sqlite")
    cur = conn.cursor()
    data = cur.execute(sql).fetchall()
    cur.close()
    conn.close()
    return data

data = sql_execute("SELECT * FROM product")

Если же у вас предполагаются разные запросы, не только fetchall, то я бы предложил лучше написать класс, который будет уметь выполнять разные запросы. И реализовать в нём менеджер контекста через __enter__ и __exit__ примерно так:

class SQL():
    def __enter__(self):
        self.conn = sqlite3.connect("db.sqlite")
        self.cur = self.conn.cursor()
        return self
    def __exit__(self, type, value, traceback):
        #Exception handling here
        self.cur.close()
        self.conn.close()
    def fetchall(self, sql):
        return self.cur.execute(sql).fetchall()

with SQL() as sql:
    data = sql.fetchall("SELECT * FROM product")

Ну и добавить ещё какие нужно виды запросов туда.

Код с классом я не проверял, но вроде как-то так должно работать.

→ Ссылка