幸福

如人饮水,冷暖自知

Python脚本助力Laravel一键生成所有模型

岁月蹁跹人知否,花开雪融又一秋。青丝已换满白头,谁知此生几回眸?

因为喜好编程,曾经数度跨行一门心思的扎进IT圈,不知不觉已历经些许年头,尤记得刚入行时那年的煎熬,对我而言一些都是新鲜事物,工作也好、休闲也罢,无时不刻不在汲取知识、学习专业技术。那年带我的飞哥,现不知身在何处,但那时候对我说过的话,尤历历在目,飞哥曾经对我说:“编程路漫漫,等到一定阶段后,缺的不是解决问题的方法,而是采用何种方法来解决问题,也即编程思路”。

在后来的工作中,随着经验的积累自己愈发体会到这一点,对于技术人员而言,首先思想上不能固步自封,应纳百家之长,将多项技能融合后,可极大的辅助日常开发工作,提升开发效率等。现就选用Laravel框架作为日常项目开发时,利用Python脚本来如何提升开发效率。

事情的起因是筹备部门技术分享,也悉心整理了个PPT,打算对Laravel框架做些讲解,准备实例的过程中突发的灵感,Laravel拥有强大的artisan命令,对于日常的开发还是十分便利的,其一就是Model的管理,我们讲MVC,Model层自然是不可忽略的一环,一般大型项目建模完成,库中如果涉及的表过多的话,在项目搭建之初,若逐一通过Laravel的artisan来创建Model的话,也是个“体力活”,于是就假象是否可以通过Python脚本来调用artisan命令批量生成Model,兴起就一个字“干”!!!

首先得理一下思路,我们先看一下Laravel模型的基本信息,这也是在此次技术分享PPT中整理了的,范例如下:


namespace App;

use Illuminate\Database\Eloquent\Model;

class Goods extends Model{

    //定义表名

    protected $table = 'jobs';

    //黑名单属性,不进行批量赋值

    protected $guarded = ['price'];

    //Eloquent默认每张表的主键名为 id,你可以在模型类中定义一个 $primaryKey 属性来覆盖该约定

    protected $primaryKey = ['uuid'];

    //时间戳是否自动更新

    public $timestamps = false;

    //模型日期列的存储格式

    protected $dateFormat = ‘U';

    //自定义用于存储时间戳的字段名称

    const CREATED_AT = ‘add_date';

    const UPDATED_AT = 'up_date';

    //数据库连接

    protected $connection = 'mysql2';

上述范例中,我们可以看到注释项里包含多种属性,这个不是全部必须的,可以根据开发场景选用,比如多库连接时,可以指定连接等。

我们再来了解下artisan创建model的命令行:


php artisan make:model Models/Goods

默认创建完的Model,里面是没有上述类似于“protected、public”等属性的,但是可以找出共性,即表名的定义,因此在通过Python脚本自动生成模型时,也可以进一步的填充此项,提升开发效率,至于需要额外维护的Model属性或是关联模型等,可以单独去修改。

实现思路如下:
  • 通过Python脚本连接指定数据库
  • 通过“SHOW TABLES”获取数据库中所有数据表
  • 遍历依次获取表名
  • 因为表中可能存在带下划线的命名,可以通过公共方法统一将表名字批量转义成驼峰命名方法,以契合Laravel中Model的命名规范
  • 调用系统函数执行artisan命令,逐一生成Model
  • 逐一生成Model的过程中,在完成每个基础模型的创建后,再依次读取Model内容,填充指定的表名等属性,然后完成复写
实现脚本如下:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import pymysql
import os
import re

conn = pymysql.Connect(host='127.0.0.1', user='root', passwd='password', db='dbname', charset='utf8')
cursor = conn.cursor()

"""
将下划线分隔的名字,转换为驼峰模式
:param src:
:param firstUpper: 转换后的首字母是否指定大写
:return:
"""
def formatter(src: str, firstUpper: bool = True):
    arr = src.split('_')
    res = ''
    for i in arr:
        res = res + i[0].upper() + i[1:]

    if not firstUpper:
        res = res[0].lower() + res[1:]
    return res


def main():
    proPath = input(" 请输入项目路径:")
    print("\n")
    query = "SHOW TABLES"
    cursor.execute(query)
    result = cursor.fetchall()
    sum = 0
    for i,item in enumerate(result):
        originalName = item[0]
        tableName = item[0]
        # tableName = item[0].capitalize()
        newName = formatter(tableName)
        modelFile = str(proPath) + "/app/Models/" + str(newName) + ".php"
        if os.path.isfile(modelFile):
            print(modelFile)
            print("...当前文件已经存在,已帮您跳过此项\n")
        else:
            sysInstru = "php artisan make:model Models/" + str(newName)
            print("---> " + sysInstru)
            os.system('cd %s && %s'%(proPath, sysInstru))
            sum = sum + 1

            fp = open(modelFile, "r+")
            content = fp.readlines()
            nfp = open(modelFile, "w")
            new = []
            for line in content:
                regex = r'(//)'
                merLine = re.search(regex, line)
                if not merLine:
                    new.append(line)

                if merLine:
                    new.append("\tprotected $table = '%s';\n" %(originalName))
                    new.append("\tprotected $guarded = ['id'];\n")

            for item in new:
                nfp.write(item)

            fp.close()
            nfp.close()

    print("\n脚本已为您自动生成 %s 个模型" %(str(sum)))
    print("\n")


if __name__ == '__main__':
    main()
    cursor.close()
    conn.close()

脚本特点

运行脚本只需要输入Laravel项目路径即可,脚本为批量生成的模型指定了一个Models文件目录,执行中有检测当前模型是否存在,可以避免重复,目前脚本为批量生成的模型定义了两个通用属性“table、guarded”,如下:

new.append("\tprotected $table = '%s';" %(originalName))
new.append("\tprotected $guarded = ['id'];")

若需要Model支持其它属性,可以编辑上述脚本添加直接相应属性,脚本执行效果如图:

 

WX20190517-165017@2x.png
检测重复生成模型的效果
WX20190517-165421@2x.png
模型内容效果
WX20190517-170859@2x.png


去打赏

您的支持将鼓励我们继续创作!

[微信] 扫描二维码打赏

[支付宝] 扫描二维码打赏

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注