最适合入门的Laravel初级教程 (七) 表迁移Migrations

看到这的时候我默认你已经配置好数据库了;
我们开始对数据库操作了;
但是前提是我们得有表啊;
说到数据库说到表;
做开发的小伙伴们肯定理解到过其中的苦于泪;
还是环境的问题;
每个同事都有一个自己的本地环境;
还有测试环境、生产环境;
团队合作的时候为了避免代码冲突;
以及方便记录修改历史和回退;
我们有版本控制比如说 git;
但是数据库怎么搞呢?
在远古时代;
在中小公司中;
在没有一套比较好用的管理表变动的方案的时候;
相信童鞋们多少都经历过改数据库的痛苦;
每次自己在本地增加了表;
或者修改了表字段;
都要记录下来告知其他同事;
其他每个同事都要在自己的本地修改表结构;
然后还要心惊胆战的修改测试环境和生产环境的数据库结构;
这种经历想想都痛苦;
但是自从有了 laravel ;
腰不酸了;腿不疼了;
一口气同步所有环境的表结构也不费劲了;

那 laravel 用的什么样的钙片来帮助我们的呢?
这就要说 laravel 内置了表迁移的功能;
它的作用就是提供数据库级的版本控制;
能保留表的变动记录;
可以回退到某个版本;
可以同步各个环境的表和结构;
虽然肯定是不像 git 那样强大;
但是已经可以极大的提升开发效率了;

我们来创建一个表迁移感受下;
当然这个肯定也不需要手动创建文件了;
命令行如下;

php artisan make:migration create_articles_table

articles 就是我们要创建的表名;
这里需要顺便提一嘴的是;
laravel 默认表都是复数形式;
那再顺便提一嘴;
config/database.php 文件中的 connections 的 prefix 可以设置每种数据库的表前缀;
迁移的时候不需要为每张表指定表前缀;
我们运行上面的命令后;
会在 database/migrations 目录生成一个迁移文件;
在这里插入图片描述
你运行的时候肯定不会跟我这个文件名一样;
因为我们很容易就发现这个文件加了时间前缀;
也就是说我是在 2018-01-06 11:29:15 创建的这个文件;
这样可以避免文件重复;
可以记录文件创建的时间;
还可以让文件按时间排序;
除了我们创建的 articles 表迁移文件;
我们还发现了 laravel 框架自带的 2014 年的 users 表和 password_resets 表;
我们是不是隐隐约约感觉到了 laravel 连用户和重置密码的功能都自带了?
这个咱们按下先不讲;
直接打开 2014_10_12_000000_create_users_table.php ;
我们来参考下它的内容;
在这里插入图片描述
里面有 up 和 down 2 个方法;
在 up 中我们看到了 create ;
在 down 中我们看到了 drop ;
根据这两个关键字;
我们基本可以理解这两个方法的作用了;
up 方法就是用来创建表的;
down 方法是用来删除表的;
当我们想回退的时候就是要执行 down 方法;
再来看详细的代码;

Schema::create('users', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->string('email')->unique();
    $table->string('password');
    $table->rememberToken();
    $table->timestamps();
});

直接就读吧;
要 create 一个 users 表;
指定这个 table 的主键字段为 id ;
指定 name 字段为字符串类型;
指定 email 字段为字符串类型并且限制唯一性;
rememberToken 就是加一个记住我的字段;
这个字段不通用就不多讲;
重点要说下 timestamps ;
$table->timestamps(); 的作用是给表增加 created_at 和 updated_at;
它们的类型是 timestamps ;
laravel 插入和编辑数据的时候会自动通过这两个字段记录操作的日期时间;

这我们就发现了 laravel 的又一特点;
整个项目对于各种命名的斟酌;
很多时候我们即便不看文档;
甚至不看源代码注释;
只看方法名就能猜到作用了;
她不只是一个框架;
还是我们编程的一个范本;

参考了 users 表我们回到 2018_01_06_112915_create_articles_table.php ;
通过命令行生成文件的同时自动已经生成了下面这样的代码;

/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
    Schema::create('articles', function (Blueprint $table) {
        $table->increments('id');
        $table->timestamps();
    });
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    Schema::dropIfExists('articles');
}

很明显;
laravel 默认表的主键字段名为 id ;
然后默认表有 created_at 和 updated_at 字段;
增删改查不分家;
增和改都默认有了个字段记录操作日期了;
那删怎么能没有呢?
没错;laravel 又为我们设计好了;

$table->softDeletes(); 

这个方法就是为表增加一个 deleted_at ;
laravel 会在删除数据的时候记录操作日期;
具体到我们的文章的时候就是回收站的功能了;
我们可能会删除文章;
但是我们还希望能恢复删除的文章;
当某篇文章的 deleted_at 为 null 的时候表示正常;
当有日期的时候就表示这篇文章是在这个日期被删掉了;

我们再次回到 2018_01_06_112915_create_articles_table.php ;
文章一般是有所属的分类的;
我们用 int 类型的 category_id 表示分类的id;
并且用 unsigned 表示无符号;
用 default 设置默认值为0;
用 comment 写注释;

$table->integer('category_id')->unsigned()->default(0)->comment('分类id');

再加一个 text 类型的文章内容字段 content ;

$table->text('content')->comment('文章内容');

我们就设计了一个简易的文章表了;

Schema::create('articles', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('category_id')->unsigned()->default(0)->comment('分类id');
    $table->string('title')->comment('标题');
    $table->text('content')->comment('内容');
    $table->timestamps();
    $table->softDeletes();
});

在之前讲 artisan 的时候说过 artisan 主要2个作用;
最适合入门的laravel入门教程(四) ;
1是创建文件;
2是执行任务;
我们已经用 artisan 创建控制器和迁移了;
现在终于到了执行任务的时候了;
我们上面的迁移文件定义了表的结构;
执行迁移才会真正生成表;

php artisan migrate

执行上面的命令我们可以看到这样的提示;
在这里插入图片描述
这意思就是我们的迁移已经完成了;
那我们再执行一遍命令呢?
我们会看到这样的的提示;

Nothing to migrate.

嗯哼?也就是说已经成功的迁移并不会重复执行;
这是在哪控制的呢?
我们 show 下 table;
在这里插入图片描述
除了 laravel 自带的 users 表和 password_resets 表 ;
除了我们创建的 articles 表;
我们还发现了个 migrations 表;
我们看下这个表的内容;
在这里插入图片描述
我们的3个迁移文件名都在里面记录着了;
说明这个表里面存的是已经执行过的迁移的文件名;
再查看下 articles 表的结构;
在这里插入图片描述
perfect跟我们迁移文件中写的是一样的;
表就这么轻松的创建了;
但是再认真看会发现并没有 string 类型;
肯定的喽;因为 mysql 压根就没 string;
string 就是 varchar 了;
再但是再认真看还会发现除了 timestamp ;
其他的字段都多了个 NOT NULL ;
这个我们并没有在迁移中指定;
这里就需要解释下了;
这个 NOT NULL 是 laravel 为我们默认添加的;
那如果确实有字段想让它允许为 NULL 怎么办呢?
别担心; laravel 还有个 ->nullable();
我们这里讲了最常用的 int 、 varchar 、 text;
那更多的类型呢?
这时候就是 laravel 官方手册真正的作用了;
laravel 官方手册更适合作为一本工具书;
我们去像查字典一样去查工具书就可以了;
就像新华字典;
它并不适合用来入门学习汉语;
但适合我们去查询;

创建表的方式我们已经学会了;
除了创建表;
我们还经常需要改变表结构;
默认的 users 并没有 deleted_at 字段;
我们如果想为 用户 也增加一个类似回收站的字段怎么办呢?
我们再来创建一个表迁移文件;

php artisan make:migration add_deleted_at_to_users_table

在 add_deleted_at_to_users_table 文件中添加如下代码;

/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->softDeletes();
    });
}

up 中就是我们迁移的内容;
创建表的时候我们使用的是 Schema::create;
编辑表的时候我们使用的是 Schema::table
然后回调函数中的内容跟创建表的时候的格式是一样的;
运行迁移;

php artisan migrate

在这里插入图片描述
deleted_at 就这么加上了;
down 方法中就是回退的内容了;

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    Schema::table('users', function (Blueprint $table) {
        $table->dropColumn('deleted_at');
    });
}

创建表的时候 down 中是 drop 表;
添加字段的时候 down 中的自然就是 drop 字段了;
我们一直在说回退;
说 laravel 的迁移功能可以让我们回退到某个状态;
那到底是怎么回退呢?
其实也很简单同样是运行命令;
为了更深刻的理解 migrations 表的作用;
在运行回退命令前我们先看下 migrations 表的内容;
在这里插入图片描述
一共有4条记录;3条创建表的;1条添加字段的;
好我们来运行回退命令;

php artisan migrate:rollback

然后再来看 migrations 表和 users 表;
在这里插入图片描述
一切如我们所料;
migrations 表的第4条添加字段的记录没有了;
users 表的 deleted_at 字段也没了;
再回退一次就把第一次运行迁移的时候的3张表就全删了;
如果再运行迁移命令一切就又有了;

到这里创建表、删除表、添加字段、删除字段我们都会了;
最后再来讲个修改字段的;
修改字段需要借助dbal扩展包;
先来安装;

composer require doctrine/dbal

剩下的工作也很简单;
我们这里举个栗子;
文章的分类也没几个;
用 int 类型太奢侈了;
我们改成 tinyint 就足够了;
老规矩先创建一个迁移文件;

php artisan make:migration change_category_id_in_articles_table

然后在 up 中写上修改的内容即可;

/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
    Schema::table('articles', function (Blueprint $table) {
        $table->tinyInteger('category_id')->unsigned()->default(0)->comment('分类id')->change();
    });
}

你以为我是要结束本篇文章的吗?
NO;
我是来讲另一个坑的;
如果运行上面这个迁移文件是会报错的;
因为 dbal 并不支持修改成 tinyInteger ;
为了兼容更多类型的数据库;
需要使用替代方案;
使用 boolean 类型;

/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
    Schema::table('articles', function (Blueprint $table) {
        $table->boolean('category_id')->unsigned()->default(0)->comment('分类id')->change();
    });
}

那 down 里面就是相反的内容了;

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    Schema::table('articles', function (Blueprint $table) {
        $table->integer('category_id')->unsigned()->default(0)->comment('分类id')->change();
    });
}

那顺便总结成一句话了;
up 中写需要迁移的内容;
down 中写回退的内容;

转自:白俊遥博客 https://baijunyao.com

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Django使用UTC时间来存储日期和时间,因此在使用时区时需要进行转换。如果你的Django应用程序的时区设置不正确,可以根据以下步骤进行调整: 1. 确保在settings.py文件中设置了正确的时区。例如,如果你位于中国,则可以将时区设置为'Asia/Shanghai'。 ```python TIME_ZONE = 'Asia/Shanghai' ``` 2. 如果你的数据库存储的是UTC时间,但是你想在管理界面和视图中显示本地时间,可以使用Django提供的timezone模块来进行转换。例如,你可以使用`timezone.localtime()`函数将UTC时间转换为本地时间。 ```python from django.utils import timezone local_time = timezone.localtime(utc_time) ``` 3. 如果你的数据库存储的是本地时间,但是你想在管理界面和视图中显示UTC时间,可以使用Django提供的timezone模块来进行转换。例如,你可以使用`timezone.make_aware()`函数将本地时间转换为UTC时间。 ```python from django.utils import timezone utc_time = timezone.make_aware(local_time, timezone.utc) ``` 4. 如果你的数据库中的数据已经存储了错误的时区信息,可以使用Django提供的`django.utils.timezone.activate()`和`django.utils.timezone.deactivate()`函数来进行时区转换。例如,如果你的数据库中存储的是以太平洋时间为基准的时间,但是你想在管理界面和视图中显示本地时间,可以使用以下代码进行转换: ```python from django.utils import timezone timezone.activate('America/Los_Angeles') local_time = timezone.localtime(utc_time) timezone.deactivate() ``` 以上是一些调整Django时区的方法,你可以根据自己的实际需求选择合适的方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值