【问题标题】:Python MySQLdb - Connection in a classPython MySQLdb - 类中的连接
【发布时间】: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 提交的,因为它是一个函数

标签: python python-3.x mysql-python


【解决方案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: 上下文中使用时返回此类的实例化版本。
    • 更多信息在这里:stackoverflow.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 感谢这个解决方案,我们是否需要担心关闭连接/光标?
    猜你喜欢
    • 2011-03-11
    • 1970-01-01
    • 2012-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    • 2014-01-01
    • 2016-06-08
    相关资源
    最近更新 更多