【问题标题】:How to drop a database in Laravel 6?如何在 Laravel 6 中删除数据库?
【发布时间】:2020-01-09 11:23:51
【问题描述】:

所以我有一个问题,我有一个多租户应用程序,我有一个系统,我可以使用标准 CRUD 操作管理所有这些租户。我希望能够在租户被删除时删除租户数据库,但我似乎在文档中找不到任何关于能够做到这一点的内容,我也无法在 API 文档中找到一系列可以使用的方法。

我在网上看到了以下内容(我能找到的唯一信息),但它已有 2 年历史,但所有这些方法要么已被弃用,要么已在 Laravel 6 中移动。

Schema::getConnection()->getDoctrineSchemaManager()->dropDatabase("`{$database_name}`");

通过我自己的测试,运行以下命令确实有效。

DB::statement('DROP DATABASE `foo`');

我不能做的是将一个变量绑定到这个语句:

DB::statement(DB::raw('DROP DATABASE ?', $database_name));

我还想使用标准的 Laravel 查询构建器,而不是自己清理信息。所以理想情况下,我希望能够做这样的事情:

DatabaseManager::dropDatabase($database_name);

或者这个:

$database = DatabaseManager::connect($database_name);
$database->dropDatabase();

我的猜测是我需要创建一个到 MySQL 的新连接,而我没有直接连接到单个数据库。然后执行命令删除数据库,然后关闭连接。

我将自己构建这个,但只是想知道是否有人对这个有任何想法,或者是否以前做过这个?非常感谢所有帮助。

【问题讨论】:

  • db 用户肯定有删除数据库的权限吗?我刚刚使用DB::statement(...) 进行了测试,这似乎工作正常。
  • @Rwd 是的,用户肯定有权限。刚刚测试并且它有效,我不能做的是将变量绑定到语句是我的意思。我现在会更新问题。
  • AFAIK,您不能替换表名。
  • @Rwd 没关系。我仍然不想成为处理进入查询的数据库名称的清理工作的人。 1. 看起来很脏,2. 安全性,3. Laravel 已经有了这个惊人的数据库库,这肯定是它可以处理的(即使是一点点工作)?
  • 据我所知,反引号转义足以清理数据库/表/列名称。此外,带有参数的预处理语句的目的是清理用户输入,因为我们不信任用户。您真的希望网站客户端完成诸如数据库删除之类的操作吗? (我不是说你不应该我只是说这是你需要非常认真考虑的事情)

标签: php mysql database laravel laravel-6


【解决方案1】:
  1. 打开终端

2.复制/粘贴

 $ php artisan db:wipe

味精 "成功删除所有表。"

【讨论】:

  • 感谢您的回答。我自己用我最后找到的解决方案回答了这个问题。我已经放弃了整个想法,因为它一开始就不是一个好主意。
【解决方案2】:

调查结果

经过一些研究和修改,我有两个选择。

1。 DBAL 学说

我查看了 Doctrine DBAL 库,并找到了我正在寻找的东西。管理命令执行的库。

使用起来很简单,上面问题中提到你需要执行这段代码:

Schema::getConnection()->getDoctrineSchemaManager()->dropDatabase("`{$database_name}`");

注意:为了做到这一点,您首先需要通过 composer 获取库:

composer require doctrine/dbal

深入研究了这个方法,它真的不值得额外的代码,更不用说包含一个库,因为它执行的代码如下[github]

/**
 * Returns the SQL snippet to drop an existing database.
 *
 * @param string $database The name of the database that should be dropped.
 */
public function getDropDatabaseSQL(string $database) : string
{
    return 'DROP DATABASE ' . $database;
}

这与您在选项 2 中所做的完全相同。

2。 Laravel DB::statement()

这个方法做的事情完全一样,而且更简单。只需要以下代码:

DB::statement("DROP DATABASE `{$database_name}`");

结论

TLDR;使用 Laravel 的 DB Facade 代替第三方解决方案来执行此操作。它更清晰、更容易,并且使用的代码更少。

现在我知道这样做可能没有太多理由,正如@Rwd 所指出的那样,但我将寻求以某种方式使用它来自动化清除冗余数据库的过程。我可能会构建某种形式的容器 DatabaseManager,其中每个管理器将包含一个基于实例的数据库信息版本,并包含一个处理数据库删除的方法。

感谢@Rwd 和@apokryfos 的讨论。

【讨论】:

    【解决方案3】:

    你可以创建一个 laravel 命令来删除数据库。例如:

    php artisan db:drop $database_name

    1. php artisan make:command dbDrop
    2. 内部命令/dbDrop.php:

      protected $signature = 'db:drop {database_name}';
      
      protected $description = 'Drop a database.';
      
      public function __construct()
      {
          parent::__construct();
      }
      
      public function handle()
      {
          // Fetch the defined database name
          $db_type = \Config::get('database.default');
          $connection = \Config::get('database.connections.'.$db_type);
          $host = $connection['host'];
          $username = $connection['username'];
          $password = $connection['password'];
          $database = $connection['database'];
          $this->dropDB($host, $username, $password, $database);
      }
        protected function dropDB($host, $username, $password, $database)
       {
      
      
      
              try
              {
                  $db = $this->argument('database_name');
                  // Create connection
                  $conn = new \mysqli($host, $username, $password);
                  $this->info(json_encode($conn));
                  // return $conn;
                  // Check connection
                  if ($conn->connect_error) {
                      die("Connection failed: " . $conn->connect_error);
                  } 
                  // Drop database
                  $sql = "DROP DATABASE `$db`";
                  if ($conn->query($sql) === TRUE) {
                      echo "Sucessfully dropped database $db!";
                  } else {
                      echo "Error dropping database: " . $conn->error;
                  }
                  $conn->close();
              }
              catch(Exception $e){
                  $this->info('');
                  echo "Error dropping database: $db";
                  $this->info('');
                  echo json_encode($e->getMessage());
                  $this->info('');
                  $this->info('You can try the mysql shell.');
              }
      
          }
      } 
      

    【讨论】:

    • 这不是我想做的,我想使用 Laravel QueryBuilder 以使用更好的标准。
    • 好的。如果您将来能找到类似的东西,请在此线程中发布。祝你好运
    【解决方案4】:

    从表中删除记录:

    DB::table('table_name')->delete();
    

    如果您希望截断整个表,这将删除所有行并将自动递增的 ID 重置为零,您可以使用 truncate 方法:

    DB::table('table_name')->truncate();
    

    或者使用Schema::dropIfExists('table_name');删除表

    删除数据库Schema::getConnection()->getDoctrineSchemaManager()->dropDatabase("database");

    【讨论】:

    • 我需要能够删除数据库,但谢谢。 :)
    • 我已经发布了解决方案,您也会在问题中找到您的更正。不过谢谢。 :)
    猜你喜欢
    • 2021-10-22
    • 2019-06-08
    • 1970-01-01
    • 2020-01-06
    • 1970-01-01
    • 1970-01-01
    • 2020-05-06
    • 2017-11-29
    • 2021-06-08
    相关资源
    最近更新 更多