php - Laravel 动态更改模式

标签 php laravel postgresql eloquent

我正在使用 laravel 5.8 和 postgres 开发一个项目。我有一个主数据库,一个包含每个组织的主数据和其他模式的全局模式。具有主数据的模式是默认连接。 我试图在每个模式中搜索特定的电话号码并返回电话号码出现在其中的所有模式名称。 我的第一次尝试是这样的,但是模式没有从默认模式切换,搜索也没有发生。

我的代码是这样的:

public function authenticate(Request $request)
    {

        $phone_number = $request->get('phone_number');

        $facilities = Facility::all();

        foreach($facilities as $facility) {

            $params = $facility['schema_name'];

            $connection = DatabaseConnection::setConnection($params);

            $fac = Patient::where(function ($query) use ($phone_number) {
                $query->where('phone_number', '=', $phone_number);
            });

            $facility = $fac;

        }       

        return response()->json(compact('token', 'connection', 'facility'));
    }

我有一个辅助函数,看起来像这样:

public static function setConnection($params)
    {
        config(['database.connections.onthefly' => [
        
            'driver' => 'pgsql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '5432'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'prefix' => '',
            'prefix_indexes' => true,
            'schema' => $params,
            'sslmode' => 'prefer',
        ]]);

        return DB::connection('onthefly');
    }

我还尝试使用 DB::statement("SET search_path TO $params"); 切换模式,然后再尝试不起作用的辅助函数。

任何有关如何动态切换模式的建议/引用都将不胜感激。

最佳答案

我花了一段时间才发现明显的解决方案;动态更改表名称以包含架构前缀并将连接的数据库名称设置为空字符串(非空)。

请注意,这可能会导致数据库迁移出现问题,但我不使用这些。一个潜在的解决方案是建立两个连接;一个数据库集用于迁移,另一个用于 SQL 操作。

附加信息...

MySQL 连接器使用 PDO 连接到数据库。数据库名称不是必需的;所以在数据库配置中将其设置为空字符串。

'database' => '',

我创建了一个基础模型来拦截对 getTable() 的调用。

use Illuminate\Database\Eloquent\Model as BaseModel;

class Model extends BaseModel
{
    protected ?string $schema = null;

    public function getSchema(): ?string
    {
        return $this->schema;
    }

    public function getTable()
    {
        $t = parent::getTable();
        $s = $this->getSchema();

        if ($s) {
            return $s.'.'.$t;
        } else {
            return $t;
        }
    }
}

然后在您的模型类(从您的基础模型扩展而来)中,设置模式:

class Product extends BaseModel
{
    protected ?string $schema = 'store-123';
}

这将产生如下查询:

select * from `store-123`.`products`

要使其动态化,您可以覆盖模型中的 getSchema() 并将逻辑放入其中以确定要使用的模式:

public function getSchema(): ?string
{
    // figure out what schema here
}

关于php - Laravel 动态更改模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65696624/

相关文章:

SQL - 按索引列检索行 - 性能

php - 如何在 javascript 中创建一个按钮,当用户单击该按钮时将打开 iframe?

php - 仅允许1行时删除最后插入的行SQL

php - 通过 mail() Apache+PHP5.3+sendmail 发送电子邮件时延迟 20 秒?

php - Phalcon:如何在保存之前获取/验证相关对象?

php - 使用php laravel框架连接多数据库

php - Laravel 5.4 SQLSTATE[42S22] : Column not found (but the column exists! )

sql - 使用 postgresql 设计一个缓慢变化的维度类型 2 脚本

php - ORM 调用应该在模型内部还是 Controller 内部?

java - Postgres 与 Glassfish 连接池