【问题标题】:truncate all tables in laravel using eloquent使用 eloquent 截断 laravel 中的所有表
【发布时间】:2013-09-25 09:17:19
【问题描述】:

有没有一种方法可以在 laravel 4 中使用 eloquent 或 fluent 截断数据库中的所有表?我不想指定表名,我只想截断所有表。换句话说,清空所有表。

【问题讨论】:

    标签: php database laravel eloquent fluent


    【解决方案1】:

    注意:doctrine/dbal 执行此操作需要包 运营

    所以请确保已安装 composer require doctrine/dbal

    1。获取所有表名

    $tableNames = Schema::getConnection()->getDoctrineSchemaManager()->listTableNames();
    

    2。遍历表名数组并使用 Schema Builder 截断

    foreach ($tableNames as $name) {
        //if you don't want to truncate migrations
        if ($name == 'migrations') {
            continue;
        }
        DB::table($name)->truncate();
    }
    

    帮助:如果您遇到了一些错误,例如

    SQLSTATE[42000]:语法错误或访问冲突:1701 无法截断外键约束中引用的表

    您可以禁用外键检查

    Schema::disableForeignKeyConstraints();
    

    并确保重新启用

    Schema::enableForeignKeyConstraints();
    

    【讨论】:

    • 请注意,Doctrine 作为 Laravel 4.1 中的依赖项将消失,因此当新版本发布时,此过程可能会发生变化。
    • 好点@fideloper!但至少现在在最新的 laravel/framework repo 中,该方法仍然存在 :) 希望 Taylor 在离开 Doctrine 时添加这个 listTableNames 功能。
    • 有没有办法在 Laravel 5 中做到这一点?
    • 是的,你只需要手动安装 "doctrine/dbal": "~2.5.0" 。
    • 如果不想删除迁移表,他们可以这样做php artisan migrate:reset
    【解决方案2】:

    这就是我截断数据库中所有表(包括表异常)的方式,它对我有用。

        // set tables don't want to trucate here
        $excepts = ['migrations'];
        $tables = DB::connection()
        ->getPdo()
        ->query("SHOW FULL TABLES")
        ->fetchAll();
        $tableNames = [];
    
        $keys = array_keys($tables[0]);
        $keyName = $keys[0];
        $keyType = $keys[1];
    
        foreach ($tableNames as $name) {
            //if you don't want to truncate migrations
            if (in_array($name[$keyName], $excepts))
                continue;
    
            // truncate tables only
            if('BASE TABLE' !== $name[$keyType])
                continue;
    
            \DB::table($name)->truncate();
        }
    

    【讨论】:

    • 不能在 SQLite 上工作。考虑到你有 DBAL,郝洛的回答有效。
    【解决方案3】:

    这是我基于@Hao Luo 的回答。此外,它还有以下优点:

    1. 不需要安装任何额外的包(不需要学说)
    2. 它非常支持 Laravel 5(或更新版本)
    3. 它禁用外键约束(如果你在不关心订单的情况下截断并启用外键约束,你可能会得到一个错误)

    代码如下:

    DB::statement("SET foreign_key_checks=0");
    $databaseName = DB::getDatabaseName();
    $tables = DB::select("SELECT * FROM information_schema.tables WHERE table_schema = '$databaseName'");
    foreach ($tables as $table) {
        $name = $table->TABLE_NAME;
        //if you don't want to truncate migrations
        if ($name == 'migrations') {
            continue;
        }
        DB::table($name)->truncate();
    }
    DB::statement("SET foreign_key_checks=1");
    

    希望你喜欢! :)

    【讨论】:

    • 很好,它适用于 MySQL 上的 laravel 5.7,不需要额外的包。谢谢。
    • @fzyzcjy,它现在在我的生产中,我做了一个单元测试来测试我所有使用这块的播种机。太棒了!!!
    • @YevgeniyAfanasyev 太好了!
    【解决方案4】:

    在 laravel 5 中,migrate:fresh 将删除数据库中的所有表(即使表与 migrate 无关)

    【讨论】:

      【解决方案5】:

      根据之前的答案,我将表名直接过滤到 SQL 查询中。我同意这是一个小的优化,但可以避免不必要的循环。

      protected function truncateDatabase($excepts = []): void
      {
          $excepts = array_merge(['migrations'], $excepts);
          \DB::statement('SET foreign_key_checks=0');
          $table_names = \DB::query()->select('TABLE_NAME')->from('information_schema.tables')
              ->where('TABLE_SCHEMA', \DB::getDatabaseName())
              ->whereNotIn('TABLE_NAME', $excepts)
              ->get()
              ->pluck('TABLE_NAME')
              ->toArray();
          foreach ($table_names as $table_name) {
              \DB::table($table_name)->truncate();
          }
          \DB::statement('SET foreign_key_checks=1');
      }
      

      【讨论】:

        【解决方案6】:

        使用这个:

        $tables = DB::select('SHOW TABLES');
        // it do truncate all tables in database
           foreach($tables as $table){
              if ($table == 'migrations') {
                  continue;
              }
              DB::table($table->Tables_in_portal_test)->truncate();
        }
        

        记住你导入

        使用 Illuminate\Support\Facades\DB;

        PD:Tables_in_YOUR_DATABASE_NAME

        【讨论】:

          【解决方案7】:

          你可以在你的基础测试用例类中添加它

              protected static function truncateTableAll(array $skip = [])
              {
                  Schema::disableForeignKeyConstraints();
                  
                  foreach (Schema::getConnection()
                               ->getDoctrineSchemaManager()
                               ->listTableNames() as $name) {
                      
                      if ($name == 'migrations' || in_array($name, $skip)) {
                          continue;
                      }
                      DB::table($name)->truncate();
                  }
                  
                  Schema::enableForeignKeyConstraints();
              }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-04-10
            • 2014-11-28
            • 2010-12-14
            • 1970-01-01
            • 1970-01-01
            • 2010-09-14
            • 2015-01-18
            • 1970-01-01
            相关资源
            最近更新 更多