我正在使用Laravel的现有项目,并且该现有项目已经具有模型,这里是一个示例:
<?php
/**
* Created by Reliese Model.
* Date: Fri, 20 Apr 2018 08:56:36 +0000.
*/
namespace App\Models;
use Reliese\Database\Eloquent\Model as Eloquent;
/**
* Class PdTcountry
*
* @property int $pkcountry
* @property string $country_code
* @property string $country_name
* @property string $country_localName
* @property string $country_webCode
* @property string $country_region
* @property string $country_continent
* @property float $country_latitude
* @property float $country_longitude
* @property string $country_surfaceArea
* @property string $country_population
* @property string $country_postcodeexpression
* @property \Carbon\Carbon $create_at
* @property \Carbon\Carbon $update_at
*
* @property \Illuminate\Database\Eloquent\Collection $pd_tregions
*
* @package App\Models
*/
class PdTcountry extends Eloquent
{
protected $table = 'pd_tcountry';
protected $primaryKey = 'pkcountry';
public $timestamps = false;
protected $casts = [
'country_latitude' => 'float',
'country_longitude' => 'float'
];
protected $dates = [
'create_at',
'update_at'
];
protected $fillable = [
'country_code',
'country_name',
'country_localName',
'country_webCode',
'country_region',
'country_continent',
'country_latitude',
'country_longitude',
'country_surfaceArea',
'country_population',
'country_postcodeexpression',
'create_at',
'update_at'
];
public function pd_tregions()
{
return $this->hasMany(\App\Models\PdTregion::class, 'fkcountry');
}
}
我的问题是,有了这个Model,是否可以通过php artisan从该模型创建数据库表?如果有一个php artisan命令可以对我所有的模型进行超级处理。
在我的数据库文件夹中,有这些,但我不知道它们的作用。
答案 0 :(得分:4)
如果您希望自动生成这些表,则不会,Laravel确实没有办法做到这一点。从理论上讲,您可以编写自己的命令来为每个模型生成迁移文件,但是无论如何仍然需要您提供所有列名,数据类型等。例如,看一下Laravel的make:migration
命令。它仅使用存根文件,并在生成(vendor/laravel/framework/src/Illuminate/Database/Migrations/MigrationCreator.php
)时替换关键字。如果您有大量需要数据库表的模型,那么这可能是您学习的好方法。
但是,如果不是这样,您最好使用标准命令生成迁移,并为其提供--create
标签。之后,您只需要在模型中定义表(或使用命名约定,以便它可以自动找到它,有关命名约定的更多信息,请参见:https://laravel.com/docs/5.6/eloquent#defining-models)。
示例:
php artisan make:migration create_my_model_table --create=my_model_table_name
如果您不使用命名约定,则将表名添加到模型中:
class PdTcountry extends Eloquent {
protected $table = "my_model_table_name"
...
}
答案 1 :(得分:1)
php artisan
通过模型创建数据库表?听起来您想要的是“代码优先设计”。 Microsoft的Entity Framework支持此功能,但是Laravel的工作方式有所不同。在带有实体框架的C#中,将创建属性(基本上是getter方法)以与每个数据库列相对应。使用Eloquent(Laravel的ORM库),它可以使用PHP magic methods动态生成这些代码,PHP变量也缺乏C#的类型。因此,无法以所需的方式基于代码填充数据库。您在问题中发布的文档注释看起来像是使用laravel-ide-helper包从数据库到代码的另一种生成方式。
或者,某些数据库客户端(例如Sequel Pro)具有将现有数据库架构导出到Laravel迁移中的插件,我发现它在过去非常快速且有用,并且可能是与工作流程最接近的东西正在寻找。祝你好运!
您应该查看相关的documentation on the Laravel website。迁移已经生成,因此您需要配置本地数据库并运行migrate
命令。这将创建应用程序所需的表和列。在更改架构时,您应该添加更多迁移,然后重新运行migrate
命令。
php artisan migrate
答案 2 :(得分:0)
正如其他人指出的那样:Laravel或确切地说是雄辩的ORM并不是这样工作的。通常,您首先要创建一个表(即进行迁移),然后再创建模型。坚持使用Laravels model conventions可以节省很多时间。
但是,您已经有一个或多个似乎缺少迁移的模型。我建议您简单地为这些模型添加迁移。不幸的是,如果您有很多模型,尤其是当您不遵循表名和其他约定时(尤其是示例模型),这将需要大量工作。
另一方面,您已经有很多要迁移的信息,可以在模型中使用。您可以从DocComments和$table
,$primaryKey
,$fillable
等属性中提取此信息。这可以自动完成。我整理了一个远未完成的示例,但至少应该使您从迁移的基础入手。然后,您可以决定手动完成其余部分,或为自动过程添加功能。如果我有很多模型,我个人只会做后者。
我已经基于您问题中包含的模型的这个示例。
正如我所说;还远远不够,请注意以下新增/改进:
switch
添加更多数据类型。将以下特征保存为app/SchemaBuilder.php
:
<?php
namespace App;
trait SchemaBuilder
{
public function printMigration()
{
echo '<pre>';
echo htmlspecialchars($this->generateMigration());
echo '</pre>';
}
public function makeMigrationFile()
{
if ($this->migrationFileExists()) {
die('It appears that a migration for this model already exists. Please check it out.');
}
$filename = date('Y_m_t_His') . '_create_' . $this->table . '_table.php';
if (file_put_contents(database_path('migrations/') . $filename, $this->generateMigration())) {
return true;
}
return false;
}
protected function generateMigration()
{
return sprintf($this->getSchemaTemplate(),
ucfirst($this->table), $this->table,
implode("\n\t\t\t", $this->generateFieldCreationFunctions()),
$this->table
);
}
protected function getSchemaTemplate()
{
$schema = "<?php\n";
$schema .= "\n";
$schema .= "use Illuminate\\Support\\Facades\\Schema;\n";
$schema .= "use Illuminate\\Database\\Schema\\Blueprint;\n";
$schema .= "use Illuminate\\Database\\Migrations\\Migration;\n";
$schema .= "\n";
$schema .= "class Create%sTable extends Migration\n";
$schema .= "{\n";
$schema .= "\t/**\n";
$schema .= "\t* Run the migrations.\n";
$schema .= "\t*\n";
$schema .= "\t* @return void\n";
$schema .= "\t*/\n";
$schema .= "\tpublic function up()\n";
$schema .= "\t{\n";
$schema .= "\t\tSchema::create('%s', function (Blueprint \$table) {\n";
$schema .= "\t\t\t%s\n"; # Actual database fields will be added here.
$schema .= "\t\t});\n";
$schema .= "\t}\n";
$schema .= "\n";
$schema .= "\t/**\n";
$schema .= "\t* Reverse the migrations.\n";
$schema .= "\t*\n";
$schema .= "\t* @return void\n";
$schema .= "\t*/\n";
$schema .= "\tpublic function down()\n";
$schema .= "\t{\n";
$schema .= "\t\tSchema::drop('%s');\n";
$schema .= "\t}\n";
$schema .= "}";
return $schema;
}
protected function generateFieldCreationFunctions()
{
$functions = [];
if (isset($this->primaryKey)) {
$functions[] = "\$table->increments('$this->primaryKey');";
}
$featuresFromDoc = $this->extractFieldDataFromCommentDoc();
$functions[] = ""; # Hack our way to an empty line.
foreach ($this->fillable as $fillableField) {
if (in_array($fillableField, $this->dates)) { # We'll handle fields in $dates later.
continue;
}
if (!isset($featuresFromDoc[$fillableField])) {
$functions[] = "//Manually do something with $fillableField";
}
switch ($featuresFromDoc[$fillableField]) {
case 'string':
$functions[] = "\$table->string('$fillableField'); //TODO: check whether varchar is the correct field type.";
break;
case 'int':
$functions[] = "\$table->integer('$fillableField'); //TODO: check whether integer is the correct field type.";
break;
case 'float':
$functions[] = "\$table->float('$fillableField', 12, 10);";
break;
default:
$functions[] = "//Manually do something with $fillableField";
}
}
$functions[] = ""; # Empty line.
foreach ($this->dates as $dateField) {
$functions[] = "\$table->dateTime('$dateField');";
}
$functions[] = ""; # Empty line.
if (!empty($this->timestamps)) {
$functions[] = "\$table->timestamps();";
}
return $functions;
}
protected function extractFieldDataFromCommentDoc()
{
$doc_comment = (new \ReflectionClass(get_parent_class($this)))->getDocComment();
preg_match_all('/@property (.+) \$(.+)/', $doc_comment, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$features[$match[2]] = $match[1];
}
return $features;
}
protected function migrationFileExists()
{
$path = database_path('migrations');
if ($handle = opendir($path)) {
while (false !== ($file = readdir($handle))) {
if (strpos($file, 'create_' . $this->table . '_table') !== false) {
return true;
}
}
closedir($handle);
}
return false;
}
}
创建以下控制器并注册一条路由,以便您可以访问它:
<?php
namespace App\Http\Controllers;
use App\PdTcountry;
use Illuminate\Http\Request;
class TestController extends Controller
{
public function index()
{
# Specify for which model you'd like to build a migration.
$buildSchemaFor = 'App\PdTcountry';
eval(sprintf('class MigrationBuilder extends %s{use \App\SchemaBuilder;}', $buildSchemaFor));
if ((new \MigrationBuilder)->makeMigrationFile()) {
echo 'Migration file successfully created.';
}
else {
echo 'Encountered error while making migration file.';
}
# Or alternatively, print the migration file to the browser:
// (new \MigrationBuilder)->printMigration();
}
}
答案 3 :(得分:0)
答案 4 :(得分:-2)
在控制台中运行php artisan migrate
。如问题图片所示,这将生成database/migrations
文件夹中现有的定义表。