Val*_*lik 0 php mysql database-migration yii2 yii2-advanced-app
我有一个任务,描述为“使用 Yii2 迁移创建新数据库,并默认使用它”。但我有一些勾结:我必须在我的main-local.php文件中设置至少一个默认数据库才能开始迁移。但我也必须通过初始迁移创建这个数据库。
return [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=default_base',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
];
Run Code Online (Sandbox Code Playgroud)
我该如何处理?创建一个带有迁移的数据库并设置为默认数据库。
当我执行迁移时(迁移文件中有代码):
public function safeUp()
{
$this->execute("CREATE DATABASE default_base");
}
Run Code Online (Sandbox Code Playgroud)
我有一个例外:
General error: 1007 Can't create database 'default_base'; database exists
Run Code Online (Sandbox Code Playgroud)
我意识到这是因为我已经在 phpmyadmin 中创建了 default_base(单击按钮“创建数据库”),并将其与我的main-local.php文件中的应用程序连接。但是我只需要在执行yii migrate.
UPD
我已经尝试了 rob006 推荐的方式,但出现连接错误
Exception 'yii\db\Exception' with message 'SQLSTATE[HY000] [1049] Unknown database 'default_base''
Run Code Online (Sandbox Code Playgroud)
我的 main-local.php 看起来就像 rob006 推荐的那样,但我仍然无法迁移。仅当我设置时才有效:
'preinstallDb' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=already_exists_db',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
Run Code Online (Sandbox Code Playgroud)
使用已经存在的数据库。我又做错了什么?
您可以定义没有数据库名称的 DSN:
'dsn' => 'mysql:host=localhost',
Run Code Online (Sandbox Code Playgroud)
并使用此连接创建数据库。
Yii::$app->preinstallDb->createCommand('CREATE DATABASE default_base')->execute();
Run Code Online (Sandbox Code Playgroud)
但是,您无法在迁移中真正创建数据库 -MigrateController需要migration表的数据库来保存迁移历史记录。在MigrateController尝试访问migration表之前,您需要创建数据库。您可以通过覆盖来做到这一点MigrateController::getMigrationHistory():
class MigrateController extends \yii\console\controllers\MigrateController {
protected function getMigrationHistory($limit) {
Yii::$app->preinstallDb->createCommand('CREATE DATABASE IF NOT EXISTS default_base')->execute();
return parent::getMigrationHistory($limit);
}
}
Run Code Online (Sandbox Code Playgroud)
并在控制台应用程序配置中使用您的控制器:
'controllerMap' => [
'migrate' => [
'class' => MigrateController::class,
],
],
Run Code Online (Sandbox Code Playgroud)
但老实说,这是带有大量硬编码的丑陋解决方案,创建一些设置实用程序可能会更好,该实用程序将在主应用程序之外执行数据库创建。通常出于安全原因,应用程序使用的数据库用户甚至不应该具有创建数据库的权限,因此您可能会重新考虑您的用例 - 您真的需要通过应用程序创建数据库吗?