top-think / top-think/think-orm

在通过Db::execute执行sql时,是否可以通过调用的模型实体类动态获取到所使用的数据库链接

Open
#799 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
PHP
Stars
437
Forks
188
PR merge metrics
No merged PRs in 30d

Description

基础环境如下:
think-orm 为4.0.49版本,framework 为 8.1.3,Mac OS,php 8.2.8

1、config/database.php 配置了数据库连接配置信息,具体如下:
`

// 数据库连接配置信息
'connections' => [
'mysql' => [
// 数据库类型
'type' => env('database.type', 'mysql'),
// 服务器地址
'hostname' => env('database.hostname', '127.0.0.1'),
// 数据库名
'database' => env('database.database', 'qifu-yigou'),
// ...
],

    // 已获资助数据库
    'mysql_publicity' => [
        // 数据库类型
        'type' => env('database.type', 'mysql'),
        // 服务器地址
        'hostname' => env('database.hostname', '127.0.0.1'),
        // 数据库名
        'database' => env('database.database', 'qifu-yigou-publicity'),
        // ...
    ],

`

2、在Publicity模型实体类中定义了模型配置参数,并且引入了ModelOperationTrait
`<?php
declare(strict_types=1);

namespace app\common\model\mysql;

use app\common\traits\ModelOperationTrait;

class Publicity extends BaseModel
{

// 引入模型操作 trait 特性
use ModelOperationTrait;

/**
 * 模型配置参数
 * @return string[]
 */
protected function getOptions(): array
{
    return array_merge(parent::getOptions(), [
        // 对应数据库连接标识(字符串或数组,默认为空),指定为 mysql_publicity
        'connection' => 'mysql_publicity',
        // 指定数据库表名(字符串,含前缀)
        'table' => 'publicity'
    ]);
}

}
`

3、定义ModelOperationTrait类,重点通过Db::execute实现数据表的truncate功能:
`<?php
declare(strict_types=1);

namespace app\common\traits;

use think\facade\Db;

/**

  • 模型操作 Trait 特性,用于复用模型操作
    /
    trait ModelOperationTrait
    {
    /
    *

    • 快捷清空当前模型对应表数据
    • @return bool
      */
      public function truncate(): bool
      {
      return $this->truncateTable($this->getTableName());
      }

    /**

    • 高效清空表数据,重置id自增起始值

    • @param string $tableName 表名,含前缀

    • @return bool
      */
      public function truncateTable(string $tableName): bool
      {
      if (!$tableName) {
      return false;
      }
      $sql = 'TRUNCATE TABLE ' . $tableName;

      /**

      • 2025.08.15 持续优化注意:???
      • Db::execute 默认链接的是 default 数据库连接,后续可持续关注是否能否动态获取当前模型的数据库连接
      • 如果有动态获取当前模型的数据库连接$connection,那么可以将 Db::execute 改为 Db::connect($connection)->execute($sql)
        */
        return Db::execute($sql) !== false;
        }

    /**

    • 获取当前模型的表名
    • @return string
      */
      public function getTableName(): string
      {
      return $this->getTable();
      }
      }
      `

4、在业务逻辑层调用,具体核心代码如下:
try { app()->make(PublicityModel::class)->truncate(); } catch (Exception $e) { // 处理异常 Log::error('清空同步中间表数据失败:' . $e->getMessage()); }

以上运行后,一直报错,报错信息如下:
清空同步中间表数据失败:SQLSTATE[42S02]: Base table or view not found: 1146 Table 'qifu-yigou.publicity' doesn't exist。

通过对报错信息进行分析,发现是在通过Db::execute执行sql时,是采用了default默认的数据库链接,即mysql。这里是否有方法可以通过Publicity模型实体类调用truncate方法时动态获取到数据库链接mysql_publicity,从而解决以上问题?或者有更好的推荐方式。期望大佬们帮忙分析看看。

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Publicity model's getOptions() connection setting and the ModelOperationTrait::truncateTable() entry point. Trace how model operations resolve connections versus the facade call to Db::execute, then inspect existing database-related tests or examples. Done means the truncate operation uses the model's mysql_publicity connection without changing the default connection.

Written by the indexing model from the issue text.

Assessment

Tech stack
mysql, php
Domain
databases
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.