为什么 php 的框架(Laravel、ThinkPHP)都不是在模型处统一定义数据库字段?

2016-04-10 11:06:09 +08:00
 gamexg

原来用 python+django ,现在正在学习 php+Laravel 。

一个地方想不明白, Laravel 为什么不像 django 一样统一在模型处定义数据库结构,而自动生成迁移脚本?

目前 Laravel 需要手写迁移及撤销迁移的变更。多次迁移后,想知道当前数据库结构只能查看多次的迁移记录或者去数据库查看当前的数据库结构了。如果将字段定义放到模型里面能清楚知道当前代码需要的数据库结构了,迁移及撤销迁移脚本是能自动生成的。

目前外键关系即需要在迁移脚本里面指定,还需要在模型里面指定,而且模型里面还需要指定两次,很奇怪的做法...

ThinkPHP 和 Laravel 都是一样的做法,在模型里面定义字段是不是有什么坑?如果没有坑的话 Laravel 有没有计划将字段定义移动到模型里面?是不是已经有开源插件实现了自动生成迁移了?

5132 次点击
所在节点    PHP
39 条回复
chareice
2016-04-10 11:11:38 +08:00
Laravel 实现的是 Active record pattern 。
gamexg
2016-04-10 11:30:51 +08:00
>一个地方想不明白, Laravel 为什么不像 django 一样统一在模型处定义数据库结构,而自动生成迁移脚本?
更正
一个地方想不明白, Laravel 为什么不像 django 一样统一在模型处定义数据库结构,自动生成迁移脚本?

@chareice 我之前说的不太明白。主要意思是为什么是手工写迁移、撤销迁移代码,手工写外键查询方法(而且两个相关表都需要分别写一个方法),运行时生成当前模型,代码里面没有当前数据库结构,想看当前的数据库结构只能去数据库查看。

而不是手工定义模型字段,自动生成迁移、外键查询方法,代码内可以统一的管理当前的数据库结构呢?至少我感觉统一管理模型字段更好些。
tabris17
2016-04-10 11:48:07 +08:00
反正我设计系统都是数据库结构驱动的,先设计表结构在写模型,反过来不习惯
whatisnew
2016-04-10 11:56:42 +08:00
migration 是个优点,多个平台的时候,数据库结构发生变化时, git pull 然后 auto migration 就好了,秒杀鸡
whatisnew
2016-04-10 11:57:05 +08:00
错了。。。是多人开发时
chloerei
2016-04-10 12:05:56 +08:00
自动生成迁移是怎么处理数据迁移的?
overtrue
2016-04-10 12:20:01 +08:00
php 语法的原因,如果说在模型里定义了字段属性,那么 ORM 的一些特性就无法实现了,比如 getXXXAttribute/setXXXAttribute ,文档译作“属性读取器与修改器”,还有一些其它特性都是依赖于 php 的魔术方法实现的。所以这应该是语言层面决定的吧。
jhdxr
2016-04-10 12:21:02 +08:00
@gamexg migration 你可以当做是数据库的版本控制。自动生成的迁移在表结构发生变化时能够处理所有情况吗?
realpg
2016-04-10 12:24:48 +08:00
什么都得像 django ?或者说什么框架都得像你觉得好的语言框架?不是人参攻击,我觉得是病得治
gamexg
2016-04-10 12:31:36 +08:00
@whatisnew 数据库结构直接保存到模型里面, pull 后不需要 auto migration ,检出代码后直接看模型代码,里面就是代码当前版本的数据库结构。不需要手写迁移脚本,修改模型后直接执行 manage.py makemigrations app 会自动根据模型字段的变化自动生成迁移脚本。提交代码时同时将迁移脚本一起提交,部署时和现在一样执行迁移脚本即可完成数据迁移。

@chareice django 模型里面包含了字段定义,修改了字段定义后执行 manage.py makemigrations app 会自动生成迁移脚本。没看代码,猜测是比较将当前模型字段和迁移脚本比较,找出变更后根据变更生成迁移脚本。提交代码时同时将模型字段和迁移脚本一起提交,实际部署时和 Laravel 一样需要执行迁移命令。

主要好处是打开模型代码就能看到代码当前版本的数据库结构,而不需要在开发环境下执行数据库迁移,然后再到数据库查看当前代码的数据库结构。
而且外键关联也可以根据模型字段自动生成,不需要在迁移里面写一份,在模型里面再写一份。

我主要是想问一下是不是已经有第三方实现了?
还没开始写项目,看 Laravel 文档就觉得麻烦,一个外键变更分别需要在迁移、撤销迁移、两个模型处做 4 次修改...
gamexg
2016-04-10 12:55:23 +08:00
@realpg 主要是觉得麻烦,一个外键变更需要分别在迁移、撤销迁移、两个模型处做 4 次修改... 如果能只写一次自动生成 4 处不方便?

@jhdxr 目前没发现不能处理的情况,添加、编辑、删除字段都能正常识别。有些破坏性迁移会给出提示,例如将允许 null 的字段修改为不允许 null ,并且没有设置默认值,生成迁移脚本时会给出多个选择。

@overtrue 有一个简单的实现方法,现存的模型、迁移都不动,直接另外增加一个新的模型,在新模型里面保存字段,每次提交代码时运行命令自动根据新模型生成原来的模型及迁移代码。也就是替换掉 php artisan make:migration 命令。
audi
2016-04-10 12:58:53 +08:00
你可以看看 symfony 嘛
chareice
2016-04-10 12:59:29 +08:00
@gamexg 原因就是数据库版本控制
chareice
2016-04-10 13:03:31 +08:00
@gamexg 在 Rails 中有一个 schema.rb 文件,会自动记录当前数据库版本和结构, Laravel 好像并没有这个,所以在 Laravel 中要观察数据库的结构,还是得到数据库里看。。
darasion
2016-04-10 13:45:29 +08:00
然并卵。
很多实际需求的变化和扭曲使得你根本用不到如此多高大上的特性。
Magician
2016-04-10 15:42:35 +08:00
Laravel 怪我咯。
msg7086
2016-04-10 16:22:40 +08:00
如果两个 PHP 系统要访问同一个数据库或者数据表怎么办?你迁移到底跑哪边的。
PS: 你要 DRY 你得试试原厂 Ruby on Rails 。别家怎么说都是移植,把一个框架从高灵活性语言移植到低灵活性语言,总会丢掉一些灵活性的。
realpg
2016-04-10 16:50:52 +08:00
@gamexg
那我给你还原一个最基本的应用场景你告诉我怎么做。
我这有一个公共数据库,有三十多个 PHP WEB 项目使用,这个库的结构和迁移在哪里定义?
wanghanlin
2016-04-10 16:50:57 +08:00
Laravel 提 issue 去 laravel/framework ,不在 laravel/laravel
gamexg
2016-04-10 17:06:26 +08:00
@msg7086 多个 php 系统之类的不是主要问题,这种情况关闭一个系统相关表的迁移即可。
迁移功能是本来就有的,我只是希望能自动生成迁移脚本。 刚刚看了一下 Ruby on Rails ,每次迁移会将数据库最新结构保存到 db/schema.rb ,能清楚知道当前版本代码的数据库结构。而 Laravel 想知道当前代码的数据库结构需要应用所有迁移后再到数据库查看结构,感觉好坑啊...

我新学 Laravel ,来这里问这个问题是想看看是不是已经有解决方案了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/269903

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX