用Python编写一个数据库类

6

我目前正在进行一个业余项目,希望编写一个面向对象的Python程序。但是我遇到的第一个问题是为我的(MySQL)数据库创建一个类。

我尽可能地想使用尽可能少的包,并尝试仅使用pymysql编写数据库类。问题在于有大量的库可供选择,而且缺乏有关在Python中编写良好的数据库类的说明。

如有建议和示例,将不胜感激。


请指定您使用的数据库。 - dizballanze
不是答案,而是另一种选择:学习如何掌握像sqlalchemy这样的大型ORM。编写自己的X似乎是一个不错的练习方式(有时确实如此),但最终你可能会错过重要的事情或对项目感到厌倦。如果你尝试理解/掌握一个设计良好且已经存在的东西,你将会遇到许多你现在甚至没有想到的边缘情况和复杂性。 - Nils Werner
我之前尝试过peewee,但感觉一般般,sqlalchemy是更好的替代选择吗? - Coen van Campenhout
2个回答

8

在遇到完全相同的情况时,我找到了mysql-connector-python类,使用该类创建了一个小的“模型”,以便从其他类中调用。这是一个精简版本,显示了各种数据库调用。正如您所看到的,我有一个配置类,其中包含所有的数据库身份验证信息等。

# dependancy: mysql-connector-python (https://dev.mysql.com/downloads/connector/python/2.1.html)
import mysql.connector
import time
import config
import HTMLParser
import StringIO

html_parser = HTMLParser.HTMLParser()

try:
    connection = mysql.connector.connect( user=config.DB_USER, password=config.DB_PASSWORD,
        host = config.DB_HOST, database=config.DB_DATABASE, unix_socket=config.UNIX_SOCKET)

    cursor = connection.cursor()

except mysql.connector.Error as err:
    logger.log('Database connection failed for '+config.DB_USER+'@'+config.DB_HOST+'/'+config.DB_DATABASE)
    exit()

def get_bad_words():
    sql = ("SELECT word FROM word_blacklist")
    results = execute(sql)
    return results

def get_moderation_method():
    sql = ("SELECT var_value FROM settings "
    "WHERE var_key = %(key)s")
    results = execute(sql, True, {'key':'moderation_method'})
    return results[0]

def current_events():
    sql = ("SELECT count(id) FROM events WHERE event_date >= DATE_SUB(NOW(), INTERVAL 2 hour) AND event_date <= DATE_ADD(NOW(), INTERVAL 5 hour)")
    results = execute(sql, True)
    return results[0]

def insert_social_post(channel, filter_type, post_id, validate, user_name, user_id, user_profile_picture, text, post_date, image_url, state):
    try:
        san_user_name = html_parser.unescape(user_name.encode('utf-8').strip()).decode("utf8").encode('ascii','ignore')
    except:
        san_user_name = html_parser.unescape(user_name.strip())
    try:
        san_text = html_parser.unescape(text.encode('utf-8').strip()).decode("utf8").encode('ascii','ignore')
    except:
        san_text = html_parser.unescape(text.strip())

    insert_post = ("INSERT IGNORE INTO social_posts "
        "(channel, filter_type, post_id, validate, user_name, user_id, user_profile_picture, text, post_date, image_url, state)"
        "VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)")
    execute(insert_post, False, [channel, filter_type, str(post_id), validate,
        san_user_name.strip(), user_id, user_profile_picture, san_text.strip(), post_date, image_url, state], True)

def delete_posts(ids):
    fmt = ','.join(['%s'] * len(ids))
    cursor.execute("DELETE FROM `social_posts` WHERE id IN (%s)" % fmt,
                    tuple(ids))
    connection.commit()

def update_campaigns(campaigns):
    sql = ("UPDATE social_campaigns "
        "SET last_updated = NOW()"
        "WHERE id IN ("+(','.join(str(c) for c in campaigns))+")")
    execute(sql, False, None, True)

def execute(tuple, single = False, args = {}, commit = False):
    cursor.execute(tuple, args)

    if commit == True:
        connection.commit()
    else:
        if single == True:
            return cursor.fetchone()
        else:
            return cursor.fetchall()

def lastrowid():
    return cursor.lastrowid

def close():
    connection.close()

可以这样调用类:

import db
bad_words = db.get_bad_words()

感谢您提供这个示例类! - NETFLOX

5
import sqlite3
"""singleton class to deal with db"""
'''same can be use for pymysql just replace the sqlite3 with pymysql'''


class DBConnection:
    instance = None

    def __new__(cls, *args, **kwargs):
        if cls.instance is None:
            cls.instance = super().__new__(DBConnection)
            return cls.instance
        return cls.instance

    def __init__(self, db_name='you-db-name'):
        self.name = db_name
        # connect takes url, dbname, user-id, password
        self.conn = self.connect(db_name)
        self.cursor = self.conn.cursor()

    def connect(self):
        try:
            return sqlite3.connect(self.name)
        except sqlite3.Error as e:
            pass

    def __del__(self):
        self.cursor.close()
        self.conn.close()

  # write your function here for CRUD operations

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接