如何在 python 电报机器人中建立(正确)运行时数据库连接?

How to make (correctly) runtime database connection in python telegram bot?

我正在使用 python+peewee+postgresql(没有 django)做我的第一个电报机器人项目。

我只是想知道,如何连接到我的数据库而不是一次(在我的项目代码的开头),而是每次需要时。例如:用户点击按钮 -> 连接打开 -> 它向 table(s)

添加行

现在文件结构如下所示:

tgbot.py

# some lines with imports

updater = Updater(TELEGRAM_TOKEN)
dp = updater.dispatcher
dp = setup_dispatcher(dp)

# some lines with logging config

updater.start_polling()
updater.idle()

dispatcher.py

# some lines with imports

# some def for event handlers
# !!!!! here will be database connections (in functions for events)

def setup_dispatcher(dp):
    db_conn = DBConnection()  # Enter database connection
    from dbmodels import db
    db = db_conn.get_connection()

    ToDo.create(...)  # creating line in postgres-table

    dp.add_handler(CommandHandler('start', start)) 
    dp.add_handler(CommandHandler('location', ask_for_location))
    dp.add_handler(MessageHandler(Filters.location, change_location)) 
    dp.add_handler(CommandHandler('today', ask_for_today))

    return dp

dbhelper.py

# some lines with imports

class DBConnection(Singleton):

    def __init__(self): ...  # initializing some variables like self.database, etc

    def get_connection(self):
        """ Creating PostgreSQL's database connection """
        if self.connection is None:
            try:
                self.connection = PostgresqlDatabase(self.database, user=self.user, password=self.password, host=self.host, port=self.port)
                self.curs = self.connection.cursor()
            except (Exception, Error) as error:
                print("PostgreSQL's connection error: \n", error)
                sys.exit(1)
        return self.connection

    def __del__(self):
        """ Closing database connection """
        if self.connection is not None:
            self.curs.close()
            self.connection.close()
        print("PostgreSQL's connection closed.")

dbmodels.py

# some lines with imports

db = PostgresqlDatabase(None)

class Singleton:
    """ Singleton realisation for database connection class in dbhelper.py """
    _instance = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

class BaseModel(Model):
    """ Basic class, used for tables-classes in models.py """
    class Meta:
        database = db

models.py

# some lines with imports

class User(BaseModel):
    """ A model for client's table """
    # initializing some fields
    class Meta:
        db_table = "clients"
    ...

class ToDo(BaseModel):
    """ A model of to-do's table """
    # initializing some fields
    class Meta:
        db_table = "to_do_s"
    ...

这完全没有必要。 peewee 数据库对象已经是单例。当你想 connect/close.

时,你只需要在上面调用 connect()close() 方法

或者,您可以将数据库实例用作 context-manager,例如:

db = PostgresqlDatabase(...)
with db:
    ToDo.create(...)