使用 eloquent 截断 laravel 中的所有表
Posted
技术标签:
【中文标题】使用 eloquent 截断 laravel 中的所有表【英文标题】:truncate all tables in laravel using eloquent 【发布时间】:2013-09-25 09:17:19 【问题描述】:有没有一种方法可以在 laravel 4 中使用 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 的回答。此外,它还有以下优点:
-
您不需要安装任何额外的包(不需要学说)
它非常支持 Laravel 5(或更新版本)
它禁用外键约束(如果你在不关心订单的情况下截断并启用外键约束,你可能会得到一个错误)
代码如下:
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();
【讨论】:
以上是关于使用 eloquent 截断 laravel 中的所有表的主要内容,如果未能解决你的问题,请参考以下文章
Laravel Eloquent Where , orWhere 和 Find 在同一个 eloquent 查询中的问题
Laravel 5.1 Eloquent isFillable() 单元测试中的差异