gon*_*ard 39 php database database-migration laravel laravel-4
我的应用程序需要预先注册的数据集才能工作.所以我需要在设置应用程序时将它们插入数据库中.
Laravel提出了两种机制:
当我读到这个描述时,这些解决方案似乎都没有适应.
在stackoverflow上已经提出了类似的问题并回答了问题.答案建议使用数据库播种器通过检测当前环境来填充数据库:
<?php
class DatabaseSeeder extends Seeder {
public function run()
{
Eloquent::unguard();
if (App::environment() === 'production')
{
$this->call('ProductionSeeder');
}
else
{
$this->call('StagingSeeder');
}
}
}
Run Code Online (Sandbox Code Playgroud)
当然,这个解决方案有效.但我不确定这是否是正确的方法,因为通过使用播种机插入数据,您将失去迁移机制提供的所有优势(数据库升级,回滚......)
我想知道在这种情况下最佳做法是什么.
Ant*_*iro 62
Laravel的发展与自由有关.那么,如果您需要为生产数据库设定种子并认为DatabaseSeeder是最佳选择,那么为什么不呢?
好的,播种机主要用于测试数据,但你会发现有些人会像你一样使用它.
我将这种重要的种子视为迁移的一部分,因为这是我的数据库表之外的事情,并且artisan migrate每次部署新版本的应用程序时都会运行,所以我只是这样做
php artisan migrate:make seed_models_table
Run Code Online (Sandbox Code Playgroud)
并在其中创建我的seedind东西:
public function up()
{
$models = array(
array('name' => '...'),
);
DB::table('models')->insert($models);
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*n B 30
我经常发现自己想知道对此的正确答案是什么.就个人而言,我没有使用种子来填充数据库中所需的行,因为你必须加载一些条件逻辑,以确保你不会尝试填充已经存在的东西.(删除和重新创建数据是非常不可取的,因为你可能最终导致密钥不匹配,如果你使用级联删除,你可能会意外擦除数据库的负载我的错误!;-)
我尽可能地将"播种"行放入迁移脚本中,数据将作为推出过程的一部分存在.
值得注意的是,您应该使用DB类而不是Eloquent模型来填充此数据,因为您的类结构可能会随着时间的推移而发生变化,这将阻止您从头开始重新创建数据库(无需重写历史记录并更改迁移文件,我确定这是件坏事.)
我倾向于使用这样的东西:
public function up()
{
DB::beginTransaction();
Schema::create(
'town',
function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
}
);
DB::table('town')
->insert(
array(
array('London'),
array('Paris'),
array('New York')
)
);
Schema::create(
'location',
function (Blueprint $table) {
$table->increments('id');
$table->integer('town_id')->unsigned()->index();
$table->float('lat');
$table->float('long');
$table->timestamps();
$table->foreign('town_id')->references('id')->on('town')->onDelete('cascade');
}
);
DB::commit();
}
Run Code Online (Sandbox Code Playgroud)
这样我就可以在第一次创建时轻松地"种子化"城镇表,并且不会干扰在运行时对其进行的任何添加.
Man*_*eet 14
This is what I use in production.
Since I run migration on each deployment
artisan migrate
Run Code Online (Sandbox Code Playgroud)
I create a seeder (just to keep seeding data out of migration for easy access later) and then run that seeder along with the migration
class YourTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
//migrate your table // Example
Schema::create('test_table', function(Blueprint $table)
{
$table->increments('id');
$table->timestamps();
$table->softDeletes();
});
//seed this table
$seeder = new YourTableSeeder();
$seeder->run();
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('test_table');
}
}
Run Code Online (Sandbox Code Playgroud)
I do not add this seed call to seeds/DatabaseSeeder.php to avoid running it twice on a new installation.
小智 6
Artisan 命令解决方案
创建一个新的 artisan 命令
php artisan make:command UpsertConfigurationTables
将其粘贴到新生成的文件中:UpsertConfigurationTables.php
<?php
namespace App\Console\Commands;
use Exception;
use Illuminate\Console\Command;
class UpsertConfigurationTables extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'upsert:configuration';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Upserts the configuration tables.';
/**
* The models we want to upsert configuration data for
*
* @var array
*/
private $_models = [
'App\ExampleModel'
];
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
foreach ($this->_models as $model) {
// check that class exists
if (!class_exists($model)) {
throw new Exception('Configuration seed failed. Model does not exist.');
}
// check that seed data exists
if (!defined($model . '::CONFIGURATION_DATA')) {
throw new Exception('Configuration seed failed. Data does not exist.');
}
/**
* seed each record
*/
foreach ($model::CONFIGURATION_DATA as $row) {
$record = $this->_getRecord($model, $row['id']);
foreach ($row as $key => $value) {
$this->_upsertRecord($record, $row);
}
}
}
}
/**
* _fetchRecord - fetches a record if it exists, otherwise instantiates a new model
*
* @param string $model - the model
* @param integer $id - the model ID
*
* @return object - model instantiation
*/
private function _getRecord ($model, $id)
{
if ($this->_isSoftDeletable($model)) {
$record = $model::withTrashed()->find($id);
} else {
$record = $model::find($id);
}
return $record ? $record : new $model;
}
/**
* _upsertRecord - upsert a database record
*
* @param object $record - the record
* @param array $row - the row of update data
*
* @return object
*/
private function _upsertRecord ($record, $row)
{
foreach ($row as $key => $value) {
if ($key === 'deleted_at' && $this->_isSoftDeletable($record)) {
if ($record->trashed() && !$value) {
$record->restore();
} else if (!$record->trashed() && $value) {
$record->delete();
}
} else {
$record->$key = $value;
}
}
return $record->save();
}
/**
* _isSoftDeletable - Determines if a model is soft-deletable
*
* @param string $model - the model in question
*
* @return boolean
*/
private function _isSoftDeletable ($model)
{
$uses = array_merge(class_uses($model), class_uses(get_parent_class($model)));
return in_array('Illuminate\Database\Eloquent\SoftDeletes', $uses);
}
}
Run Code Online (Sandbox Code Playgroud)
填充$_models您想要播种的 Eloquent 模型。
定义模型中的种子行:const CONFIGURATION_DATA
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class ExampleModel extends Model
{
use SoftDeletes;
const CONFIG_VALUE_ONE = 1;
const CONFIG_VALUE_TWO = 2;
const CONFIGURATION_DATA = [
[
'id' => self::CONFIG_VALUE_ONE,
'col1' => 'val1',
'col2' => 'val2',
'deleted_at' => false
],
[
'id' => self::CONFIG_VALUE_TWO,
'col1' => 'val1',
'col2' => 'val2',
'deleted_at' => true
],
];
}
Run Code Online (Sandbox Code Playgroud)
将命令添加到 Laravel Forge 部署脚本(或任何其他 CI 部署脚本)中:php artisan upsert:configuration
其他值得注意的事情:
deleted_at定义删除。Artisan 命令将处理调用正确的方法来删除或恢复您的记录。truefalse其他提到的解决方案的问题:
| 归档时间: |
|
| 查看次数: |
18424 次 |
| 最近记录: |