当我必须默认使用它时,如何通过 Yii2 迁移创建一个新数据库?
How to create a new database by Yii2 migration, when I have to use it by default?
我有一个任务描述为 "Creating a new database with Yii2 migration, and use it by default"。但我有一些共谋:我必须在我的 main-local.php
文件中设置至少一个默认数据库才能开始迁移。但我也必须在初始迁移时创建这个数据库。
return [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=default_base',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
];
我该如何处理?使用迁移创建数据库并将其设置为默认数据库。
当我执行迁移时(迁移文件中有代码):
public function safeUp()
{
$this->execute("CREATE DATABASE default_base");
}
我有一个例外:
General error: 1007 Can't create database 'default_base'; database exists
我意识到那是因为我已经在 phpmyadmin 中创建了 default_base(单击按钮 "created database"),并将其与我的 main-local.php
文件中的应用程序连接。
但是我只需要在执行 yii migrate
.
时创建这个基础
UPD
我已经尝试了rob006推荐的方式,但是我连接错误
Exception 'yii\db\Exception' with message 'SQLSTATE[HY000] [1049] Unknown database 'default_base''
我的 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',
],
使用已经存在的数据库。我又做错了什么?
您可以在没有数据库名称的情况下定义 DSN:
'dsn' => 'mysql:host=localhost',
并使用此连接创建数据库。
Yii::$app->preinstallDb->createCommand('CREATE DATABASE default_base')->execute();
但是您不能真正在迁移中创建数据库 - MigrateController
需要 migration
table 的数据库来保存迁移历史。您需要在 MigrateController
尝试访问 migration
table 之前创建数据库。您可以通过覆盖 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);
}
}
并在控制台应用程序配置中使用您的控制器:
'controllerMap' => [
'migrate' => [
'class' => MigrateController::class,
],
],
但老实说,这是一个带有大量硬编码的丑陋解决方案,最好创建一些设置实用程序来在主应用程序之外执行数据库创建。通常出于安全原因,应用程序使用的数据库用户甚至不应该有创建数据库的权限,因此您可能会重新考虑您的用例 - 您真的需要通过应用程序创建数据库吗?
我找到了让它对我有用的唯一方法。只是覆盖 MigrateController 中的 init()。
首先,我在 main-local.php 文件中添加了 controllerMap:
'controllerMap' => [
'migrate' => [
'class' => 'console\controllers\MigrateController',]]
然后将新的控制器放入console\controllers:
namespace console\controllers;
use yii\console\controllers\MigrateController as BasicMigrateController;
use Yii;
class MigrateController extends BasicMigrateController
{
public function init()
{
Yii::$app->preinstallDb->createCommand('CREATE DATABASE IF NOT EXISTS default_base')->execute();
parent::init();
}
}
我有一个任务描述为 "Creating a new database with Yii2 migration, and use it by default"。但我有一些共谋:我必须在我的 main-local.php
文件中设置至少一个默认数据库才能开始迁移。但我也必须在初始迁移时创建这个数据库。
return [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=default_base',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
];
我该如何处理?使用迁移创建数据库并将其设置为默认数据库。
当我执行迁移时(迁移文件中有代码):
public function safeUp()
{
$this->execute("CREATE DATABASE default_base");
}
我有一个例外:
General error: 1007 Can't create database 'default_base'; database exists
我意识到那是因为我已经在 phpmyadmin 中创建了 default_base(单击按钮 "created database"),并将其与我的 main-local.php
文件中的应用程序连接。
但是我只需要在执行 yii migrate
.
UPD
我已经尝试了rob006推荐的方式,但是我连接错误
Exception 'yii\db\Exception' with message 'SQLSTATE[HY000] [1049] Unknown database 'default_base''
我的 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',
],
使用已经存在的数据库。我又做错了什么?
您可以在没有数据库名称的情况下定义 DSN:
'dsn' => 'mysql:host=localhost',
并使用此连接创建数据库。
Yii::$app->preinstallDb->createCommand('CREATE DATABASE default_base')->execute();
但是您不能真正在迁移中创建数据库 - MigrateController
需要 migration
table 的数据库来保存迁移历史。您需要在 MigrateController
尝试访问 migration
table 之前创建数据库。您可以通过覆盖 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);
}
}
并在控制台应用程序配置中使用您的控制器:
'controllerMap' => [
'migrate' => [
'class' => MigrateController::class,
],
],
但老实说,这是一个带有大量硬编码的丑陋解决方案,最好创建一些设置实用程序来在主应用程序之外执行数据库创建。通常出于安全原因,应用程序使用的数据库用户甚至不应该有创建数据库的权限,因此您可能会重新考虑您的用例 - 您真的需要通过应用程序创建数据库吗?
我找到了让它对我有用的唯一方法。只是覆盖 MigrateController 中的 init()。 首先,我在 main-local.php 文件中添加了 controllerMap:
'controllerMap' => [
'migrate' => [
'class' => 'console\controllers\MigrateController',]]
然后将新的控制器放入console\controllers:
namespace console\controllers;
use yii\console\controllers\MigrateController as BasicMigrateController;
use Yii;
class MigrateController extends BasicMigrateController
{
public function init()
{
Yii::$app->preinstallDb->createCommand('CREATE DATABASE IF NOT EXISTS default_base')->execute();
parent::init();
}
}