Skip to content

数据库管理器

PySpigot 包括一个数据库管理器,允许您连接和与各种 SQL 数据库(包括 MySQL、MariaDB、PostgreSQL 等)以及 MongoDB 进行交互。在内部,PySpigot 利用 HikariCP 来与 SQL 类型的数据库服务器进行通信,利用 MongoDB Java 驱动程序 来与 MongoDB 数据库服务器进行通信。

要了解如何将数据库管理器导入您的脚本,请访问常规信息页面。

ℹ️ 信息

这不是一个全面的 SQL 或 MongoDB 使用指南。如果您不确定如何使用 SQL 或 MongoDB,请寻求适当的教程/信息。

SQL

数据库管理器允许您连接和与 SQL 类型的数据库进行交互。

SQL 数据库的数据库管理器用法

数据库管理器提供了几个函数可用于与 SQL 数据库进行交互。它们包括:

  • newHikariConfig(): 为了方便起见,返回一个新的 HikariConfig 对象。
  • connectSql(host, port, database, username, password): 使用提供的主机、端口、数据库名称、用户名和密码连接到远程 SQL 数据库。
  • connectSql(host, port, database, username, password, hikariConfig): 使用提供的主机、端口、数据库名称、用户名、密码以及提供的 HikariConfig 连接到远程 SQL 数据库。
  • connectSql(uri): 使用给定的连接字符串连接到远程 SQL 数据库(有关连接字符串的详细信息,请参见下文)。
  • connectSql(uri, hikariConfig): 使用给定的连接字符串(有关连接字符串的详细信息,请参见下文)以及提供的 HikariConfig 连接到远程 SQL 数据库。
  • connectSql(hikariConfig): 使用给定的 HikariConfig 连接到远程 SQL 数据库。
  • disconnect(database): 断开并关闭与数据库的连接。接受 connectSql 返回的 SqlDatabase 对象。

上面所有的 connectSql 函数都完成相同的任务:它们将初始化一个连接到远程数据库并返回一个 SQLDatabase 对象,然后可以用于在数据库内选择和更新表。您使用哪个 connectSql 函数取决于您的具体用例。其中,connectSql(host, port, database, username, password) 是最基本的,如果您刚开始使用,应该使用这个。

数据库管理器还允许您指定一个连接字符串/URI/URL,以便更精细地控制连接参数和设置。您也可以在连接字符串中指定选项。接受uriconnectSql函数是接受连接字符串的函数。

小贴士

如果您使用完数据库连接,请关闭它是一个良好的实践。如果在您的脚本停止或终止时有任何打开的数据库连接,那么这些打开的连接将被自动关闭。如果在语句的执行期间或待执行期间关闭数据库,不能保证语句的执行会发生。

HikariConfig

HikariConfig是一个配置对象,允许更多地控制SQL连接。例如,它允许您设置最小空闲时间、池大小、空闲超时时间等。有关HikariConfig的详细信息,请参阅HikariCP JavaDocs

您还可以仅使用HikariConfig对象来建立连接(通过connectSql(hikariConfig)函数)。HikariConfig对象允许您直接在对象中指定主机、端口、数据库、用户名和密码。这可能是与远程数据库建立新连接的最简单方法。

数据库管理器提供了一个newHikariConfig()函数供您方便使用。它返回一个带有默认选项的新HikariConfig,您可以进行修改。修改选项后,您可以将HikariConfig传递给connectSql函数之一。

SqlDatabase对象

一旦调用上述任何一个 connectSql 函数,就会建立一个连接。如果连接成功建立,将返回一个 SqlDatabase 对象。SqlDatabase对象包含用于直接与数据库交互的函数:

  • getHikariDataSource(): 返回底层的HikariDataSource连接对象。
  • select(sql): 使用提供的 sql 在数据库上执行一个select语句。返回一个Map(本质上与python中的字典相同),其中键代表列名,值代表列数据(对象列表)。
  • select(sql, values): 使用提供的 sql 在数据库上执行一个select语句,其中 values(对象列表)将替换sql语句中的内容。返回一个Map(本质上与python中的字典相同),其中键代表列名,值代表列数据(对象列表)。
  • update(sql): 使用提供的 sql 在数据库上执行一个更新语句。返回一个int,表示受更新影响的行数。
  • update(sql, values): 在数据库上执行一个更新语句,其中 values(对象列表)将替换sql语句中的内容。返回一个int,表示受更新影响的行数。

上述函数中的 sql 就是简单的SQL语句。例如:

1
SELECT * FROM test_table;

我们也可以定义将自动插入SQL语句的值。例如,我们可以定义一个类似以下的SQL语句:

1
SELECT * FROM test_table WHERE id = ?;
这个语句被称为参数化查询,因为它包含问号(?)。SQL语句中的问号充当占位符,即以后将插入的值。这就是values参数发挥作用的地方:问号将被传入values中的值替换。例如,如果我们调用
1
sql.select('SELECT * FROM test_table WHERE id = ?;', [10])
那么发送到服务器的实际SQL语句将是
1
SELECT * FROM test_table WHERE id = 10;
因为问号被我们在values中传入的值10替换了。如果我们想在values中传入多个值,这也适用:
1
sql.update('INSERT INTO test_table (id, val) VALUES (?, ?);', [11, 1])
上面的语句有效地变成了 INSERT INTO test_table (id, val) VALUES (11, 1);。注意,values中对象的顺序很重要,因为它决定了在SQL语句中替换占位符的顺序。第一个问号被替换为位置零处的对象,第二个问号被替换为位置一处的对象,依此类推。

SQL数据库代码示例

以下代码连接并在远程SQL数据库上执行一些简单的操作。正在交互的表名为test_table,拥有列id(自动递增,非空,唯一)和value(非空):

1
2
3
import pyspigot as ps # (1)!

db_manager = ps.database_manager() # (2)!
  1. 在这里,我们导入PySpigot作为ps以便利用数据库管理器。

  2. 在这里,我们从ps中获取数据库管理器并将其设置为db_manager

  3. 在这里,我们通过connectSql建立一个新连接,并将返回的对象分配给sql。这个变量随后将用于与数据库进行交互。

  4. 在这里,我们从test_table选择所有数据,并按照列val降序排列,将选择的数据分配给data变量。

  5. 在这里,我们循环遍历所有数据,并打印列名以及与该列对应的数据。

  6. 在这里,我们在test_table上执行更新,通过插入具有id值为11和val值为1的新行,并将结果(受影响的行数)分配给变量rows_affected

  7. 在这里,我们打印受影响的行数。

  8. 在这里,我们通过调用数据库管理器的disconnect函数并传递我们之前通过connectSql连接时获取的数据库对象来关闭数据库连接。

重要的是要记住,与任何远程数据库进行交互都是一个I/O操作。如果我们在主服务器线程上运行这段代码(即,不在一个异步任务中),那么服务器会挂起并且在与远程服务器的交互完成之前就无响应。对于延迟高或者延迟大的连接,这可能会导致服务器出现大量的延迟。为了避免延迟,最佳做法是将所有的I/O操作放在一个异步任务中。请参考下面的示例部分。

用于 SQL 数据库的代码示例,异步

以下代码采用了上面的代码示例,但是将与数据库的交互封装在了一个异步任务中。值得注意的是,与数据库的连接(第6行的connectSql函数)仍然是同步的,但我们希望它保持同步,因为连接失败会影响脚本的其余执行,如果连接失败(即出现错误),脚本应终止。

下面的代码利用任务管理器的回调任务,它会异步运行一个任务,然后通过另一个用户定义的函数在异步任务完成时回调到主服务器线程。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import pyspigot as ps

task_manager = ps.task_manager()
db_manager = ps.database_manager()

sql = db_manager.connectSql('localhost', '3306', 'test', 'root', '')

def select_data():
    data = sql.select('SELECT * FROM test_table ORDER BY val DESC;')
    return data

def sync_callback(data):
    for column, col_data in data.items():
        print(column)
        print(col_data)

task_manager.runSyncCallbackTask(select_data, sync_callback)

def update():
    rows_affected = sql.update('INSERT INTO test_table (id, val) VALUES (?, ?)', [11, 1])
    print('Rows affected: ' + str(rows_affected))
1
task_manager.runTaskAsync(update)

MongoDB

数据库管理器允许您连接到Mongo数据库并与之交互。

MongoDB的数据库管理器用法

数据库管理器提供了几个函数,供您在与MongoDB交互时使用。它们包括:

  • newMongoClientSettings(): 返回一个新的MongoClientSettings构建器,供您方便使用。
  • connectMongo(host, port, username, password): 使用给定的主机、端口、用户名和密码连接到远程MongoDB服务器。
  • connectMongo(host, port, username, password, clientSettings): 使用给定的主机、端口、用户名和密码,使用给定的MongoClientSettings连接到远程MongoDB服务器。
  • connectMongo(uri): 使用给定的连接字符串连接到远程MongoDB服务器。
  • connectMongo(uri, clientSettings): 使用给定的连接字符串,使用给定的MongoClientSettings连接到远程MongoDB服务器。
  • connectMongo(clientSettings): 使用给定的MongoClientSettings连接到远程MongoDB服务器。
  • disconnect(database): 断开并关闭与数据库的打开连接。接受connectMongo返回的MongoDatabase对象。

如果您希望对连接参数和设置进行更精细的控制,数据库管理器允许您指定连接字符串/URI/URL。您还可以在连接字符串中指定选项。接受uriconnectMongo函数是接受连接字符串的函数。

这些功能与初始化与SQL数据库连接的函数非常相似。唯一的真正区别是,我们可以使用MongoCLientSettings来指定连接设置,而不是HikariConfig。

MongoClientSettings

MongoClientSettings是一个配置对象,允许更精细地控制MongoDB连接。例如,它允许您设置连接池设置、连接字符串、加密设置、读取首选项、写入首选项等。有关MongoClientSettings的详细信息,请参阅MongoDB文档

您还可以单独使用MongoClientSettings对象来建立连接(通过connectMongo(clientSettings)函数)。MongoClientSettings构建器对象允许您直接在对象中指定连接字符串或主机、端口、数据库、用户名和密码。这可能是与远程数据库建立新连接的最简单方法。

数据库管理器提供了一个newMongoClientSettings()函数,供您方便使用。它返回一个带有默认选项的新MongoClientSettings构建器,您可以对其进行修改。一旦您根据自己的喜好修改了选项,您就可以调用对象上的build(),然后将结果传递给connectMongo函数之一。

一旦您完成为MongoClientSettings设置选项,您必须调用build()方法将这些设置构建成一个可读对象,然后将其传递给connectMongo函数之一。

MongoDatabase对象

一旦我们调用以上任何一个connectMongo函数,连接就建立起来了。如果连接成功建立,那么就会返回一个MongoDatabase对象。MongoDatabase对象包含用于直接与数据库交互的函数。

MongoDatabase对象中有太多函数,无法在此列出全部。要查看完整列表,请参阅PySpigot JavaDocs

此外,MongoDB文档中包含详细的文档和示例代码。我强烈推荐您查看有关如何使用MongoDatabase对象的信息,因为我在MongoDatabase中定义的许多函数只是对底层MongoDB库的透传。

Tip

如果您完成了对数据库连接的使用,最好将其关闭。如果在停止或终止脚本时有任何打开的数据库连接,那么这些打开的连接将会自动关闭。如果数据库在操作执行期间或待执行期间关闭,无法保证操作将会执行。

MongoDB的代码示例

以下代码建立了与远程MongoDB服务器的连接,创建了一个集合,插入了一个文档,然后检索创建的文档。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import pyspigot as ps

db_manager = ps.database_manager()

mongo = db_manager.connectMongo('localhost', '27017', None, None)

if (not mongo.doesCollectionExist('test', 'test_collection')):
    mongo.createCollection('test', 'test_collection')

mongo.insertDocument('test', 'test_collection', mongo.createDocument('test_key', 'test_value'))

documents = mongo.getDocuments('test', 'test_collection')

for document in documents:
    print(document)
提醒

以上代码是同步运行的。如上所述,最好在异步上下文中与外部数据库服务器交互,以避免服务器延迟。

摘要

  • DatabaseManager允许您连接并与SQL类型和Mongo数据库交互。
  • 使用connectSql函数(结合特定情况下提供的参数)连接到SQL数据库。
  • 使用connectMongo函数(结合特定情况下提供的参数)连接到Mongo数据库。
  • 连接到数据库时,连接函数会返回一个数据库对象(SqlDatabaseMongoDatabase),然后用于与数据库交互。
  • 与数据库交互是 I/O 操作,这些交互应该在异步上下文中进行,比如在计划的异步任务中或在回调任务中。
  • 当脚本停止时,数据库连接会自动关闭。在其他任何时候,如果完成使用数据库,应通过调用数据库管理器的disconnect函数来关闭数据库。disconnect函数需要连接到数据库时获取的数据库对象。 ```