这是在 mysql/python 中构造数据库初始化调用的正确方法吗?

问题描述 投票:0回答:1

我是 mysql、python 和 mysql Python 连接器的新手。想要学习最佳实践。我有一个初始化方法来创建数据库、创建表和/或用数据填充它(取决于缺少的内容)。

当光标被覆盖时,它是否会清理任何资源?还能做得更好吗?

def initialize(config):
    connection = None
    cursor = None

    # open the database connection
    try:
        connection = mysql.connector.connect(**config["DATABASE"]["CONNECTION"])
        cursor = connection.cursor()
    except mysql.connector.Error as err:
        print(err)
        exit(1)

    # connection successful, check if the db exists already
    name = config["DATABASE"]["NAME"]
    try:
        cursor.execute("USE {}".format(name))
    except mysql.connector.Error as err:
        print("Database {} does not exist".format(name))
        if err.errno == errorcode.ER_BAD_DB_ERROR:
            print("Creating {}...".format(name))
            try:
                cursor.execute(
                    "CREATE DATABASE {} DEFAULT CHARACTER SET 'utf8mb4'".format(name)
                )
            except mysql.connector.Error as err:
                print("Failed creating database: {}".format(err))
                exit(1)

            print("Database {} created successfully".format(name))
            # set the active database
            connection.database = name
        else:
            print(err)
            exit(1)

    # also set connection to use the new database
    config["DATABASE"]["CONNECTION"]["database"] = config["DATABASE"]["NAME"]

    # load and run schema
    # safe to do as it doesn't create tables if they exist
    with open(config["DATABASE"]["SCHEMA"], "rb") as f:
        tables = f.read().decode("utf-8").split(";")
        for table in tables:
            table = re.sub("[\n\r]", "", table)
            if len(table) > 0:
                try:
                    cursor.execute(table)
                    connection.commit()
                except mysql.connector.Error as err:
                    print(err)
                    exit(1)

    # if there is test data
    if config["DATABASE"]["DATA"] != "":
        # if the db is empty
        cursor.execute("SELECT * FROM account LIMIT 1")
        # must fetch the data for the cursor
        cursor.fetchone()
        if cursor.rowcount == 0:
            # populate
            with open(config["DATABASE"]["DATA"], "rb") as f:
                tables = f.read().decode("utf-8").split(";")
                for table in tables:
                    table = re.sub("[\n\r]", "", table)
                    if len(table) > 0:
                        try:
                            cursor.execute(table)
                            connection.commit()
                        except mysql.connector.Error as err:
                            print(err)
                            exit(1)

    # cleanup
    cursor.close()
    connection.close()
mysql-python
1个回答
0
投票

我将做出假设,您不想使用第三方库。

在这种情况下,创建上下文管理器将是使用 python 中需要清理的资源的正确方法。

这里有一个解释,

上下文管理器协助自动打开和关闭文件、网络连接和数据库连接。

以下代码是如何创建一个。这将像打开上下文管理器一样用于读取文件。

finally 块确保一旦退出 with 语句的缩进块,无论错误或成功,连接都会关闭。

import mysql.connector
from contextlib import contextmanager

@contextmanager
def mysql_connection(host, user, password, database):
    connection = mysql.connector.connect(host=host, user=user, password=password, database=database)
    cursor = connection.cursor()
    try:
        yield cursor
    finally:
        cursor.close()
        connection.close()

# Usage example:
with mysql_connection('localhost', 'your_user', 'your_password', 'your_database') as cursor:
    cursor.execute('SELECT * FROM your_table')
    result = cursor.fetchall()
    print(result)

# The connection is closed

您可以进一步修改代码,在 try catch 中添加一个 catch,以处理任何错误情况。

参考:

https://realpython.com/python-with-statement/

© www.soinside.com 2019 - 2024. All rights reserved.