Python MySQLdb - 类中的连接

Posted

技术标签:

【中文标题】Python MySQLdb - 类中的连接【英文标题】:Python MySQLdb - Connection in a class 【发布时间】:2016-10-30 18:45:30 【问题描述】:

我正在创建一个 Python 项目,我必须在其中查找和检索数据库中的数据。 我尝试创建一个类,在其中声明连接并进行查询,这就是我迄今为止所拥有的。

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';"))

所以,主要问题是变量dbcursor 不能从同一类的其他def/函数调用。我想要得到的是一个完善的查询,我可以在其中进行查询并检索它的内容。这将总结我的代码,因此我应该这样做。

【问题讨论】:

想想这一行...sql.cursor.execute(sql)... 哪个sql 变量将用于获取光标?参数,而不是类 您应该从您的问题中删除不必要的标签。它是 python 2.7 或 3,或者与版本无关。 @cricket_007 提交的,因为它是一个函数 【参考方案1】:
from config import Config
import MySQLdb

class Connection:
    def __init__(self):
        self.db=MySQLdb.connect(
            Config.DATABASE_CONFIG['server'],
            Config.DATABASE_CONFIG['user'],
            Config.DATABASE_CONFIG['password'],
            Config.DATABASE_CONFIG['name']
            )
        self.db.autocommit(True)
        self.db.set_character_set('utf8mb4')
        self.cur=self.db.cursor()

示例配置类(config.py):

class Config(object):

  DATABASE_CONFIG = 
          'server': 'localhost',
          'user': 'dbuser',
          'password': 'password',
          'name': 'dbname',
          

【讨论】:

【参考方案2】:

我通常使用psycopg2 / postgres,但这是我经常使用的基本DB类,以Python的SQLite为例:

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.close()

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

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

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

    def close(self, commit=True):
        if commit:
            self.commit()
        self.connection.close()

    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()

这将允许您使用Database 类,通常像db = Database('db_file.sqlite) 或在with 语句中:

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

with 语句退出时,连接会自动提交并关闭。

然后,您可以将您经常执行的特定查询封装在方法中并使其易于访问。例如,如果您正在处理交易记录,您可以有一种方法来按日期获取它们:

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

下面是一些示例代码,我们在其中创建了一个表,添加了一些数据,然后将其读回:

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)

我希望这会有所帮助!

【讨论】:

华丽的答案!非常感谢,我还是不明白__enter__ 的说法,当你return DBase 时,会发生什么。 __enter____exit__“魔法方法”让类使用with 语句。它基本上是说在 with DBase() as db: 上下文中使用时返回此类的实例化版本。 更多信息在这里:***.com/questions/1984325/… 你不应该关闭 DBase.__exit__() 中的光标吗?如果不是,为什么?谢谢! 至少在pyscopg2(Python 的 postgres 客户端)中,当您关闭连接时,光标会自动关闭,所以我不会费心去明确地这样做。这很可能会为您解决。【参考方案3】:

您可以使用构造函数进行连接。当创建类的对象时,构造函数会自动调用。

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()

【讨论】:

欢迎来到 SO。 :) 这与现有答案有何不同甚至更好?【参考方案4】:

这不是您在 Python 中编写类的方式。您需要在__init__ 方法中定义您的连接和光标,并通过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

【讨论】:

这对我帮助很大!谢谢,我没有意识到我可以将它们添加到__init__ 你如何称呼这些课程?喜欢:print(sql.query("select * from test")) @Daniel Roseman 感谢这个解决方案,我们是否需要担心关闭连接/光标?

以上是关于Python MySQLdb - 类中的连接的主要内容,如果未能解决你的问题,请参考以下文章

python2中MySQLdb加入超时及其重试功能

Ubuntu中的Python-MySQLdb错误

python之MySQLdb模块

python MySQLdb连接mysql时报错

Python2 - MySQL适配器 MySQLdb

python 2.x MysqlDB模块使用