web-dev-qa-db-fra.com

Python MySQLdb - Connexion à une classe

Je réalise un projet Python dans lequel je dois rechercher et récupérer des données d’une base de données.
J'ai essayé de faire un cours, dans lequel je déclare la connexion et fais mes requêtes, voici ce qui me manque le plus jusqu'ici. 

import MySQLdb
dbc =("localhost","root","1234","users")
class sql:
    db = MySQLdb.connect(dbc[0],dbc[1],dbc[2],dbc[3])
    cursor = db.cursor()

    def query(self,sql):
        sql.cursor.execute(sql)
        return sql.cursor.fetchone()

    def rows(self):
        return sql.cursor.rowcount

sqlI = sql()
print(sqlI.query("SELECT `current_points` FROM `users` WHERE `nick` = 'username';"))

Le problème principal est donc que les variables db et cursor ne peuvent pas être appelées à partir d'autres fonctions/def de la même classe. Ce que j'aimerais obtenir, c'est une requête soignée, dans laquelle je peux faire des requêtes et en retrouver le contenu. Cela résumerait mon code, donc je devrais le faire.

7
Marçal Torà

J'utilise habituellement psycopg2/postgres, mais c'est la classe de base de base de données que j'utilise souvent, avec SQLite de Python à titre d'exemple:

import sqlite3

class Database:
    def __init__(self, name):
        self._conn = sqlite3.connect(name)
        self._cursor = self._conn.cursor()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.commit()
        self.connection.close()

    @property
    def connection(self):
        return self._conn

    @property
    def cursor(self):
        return self._cursor

    def commit(self):
        self.connection.commit()

    def execute(self, sql, params=None):
        self.cursor.execute(sql, params or ())

    def fetchall(self):
        return self.cursor.fetchall()

    def fetchone(self):
        return self.cursor.fetchone()

    def query(self, sql, params=None):
        self.cursor.execute(sql, params or ())
        return self.fetchall()

Cela vous permettra d’utiliser la classe Database soit normalement comme db = Database('db_file.sqlite), soit dans une instruction with:

with Database('db_file.sqlite') as db:
    # do stuff

et la connexion sera automatiquement validée et fermée lorsque l'instruction with sera terminée.

Ensuite, vous pouvez encapsuler des requêtes spécifiques que vous faites souvent dans des méthodes et les rendre faciles d'accès. Par exemple, si vous traitez avec des enregistrements de transaction, vous pouvez avoir une méthode pour les obtenir par date:

def transactions_by_date(self, date):
    sql = "SELECT * FROM transactions WHERE transaction_date = ?"
    return self.query(sql, (date,))

Voici un exemple de code dans lequel nous créons une table, ajoutons des données, puis les relisons:

with Database('my_db.sqlite') as db:
    db.execute('CREATE TABLE comments(pkey INTEGER PRIMARY KEY AUTOINCREMENT, username VARCHAR, comment_body VARCHAR, date_posted TIMESTAMP)')
    db.execute('INSERT INTO comments (username, comment_body, date_posted) VALUES (?, ?, current_date)', ('tom', 'this is a comment'))
    comments = db.query('SELECT * FROM comments')
    print(comments)

J'espère que ça aide!

19
carusot42

Ce n'est pas comme ça que vous écrivez des classes en Python. Vous devez définir votre connexion et votre curseur dans la méthode __init__, et y faire référence via self.

class sql:

    dbc = ("localhost","root","1234","users")

    def __init__(self):
        db = MySQLdb.connect(*self.dbc)
        self.cursor = db.cursor()

    def query(self,sql):
        self.cursor.execute(sql)
        return self.cursor.fetchone()

    def rows(self):
        return self.cursor.rowcount
7
Daniel Roseman

Vous pouvez utiliser le constructeur pour la connexion. Lorsque l'objet de classe sera créé, le constructeur l'invoquera automatiquement.

import MySQLdb

class Connection:
    def __init__(self):
        self.con=MySQLdb.connect("127.0.0.1","root","","db_name",3306)
        self.cmd=self.con.cursor()
obj=Connection()
0
Ashish Mishra