前言

如果通过java生成实体类,可以通过mybatis或者mybatis-plus的generator。

而sqlalchemy也可以生成实体类,通过sqlalcodegen或者flask-sqlalcodegen。

使用flask-sqlalcodegen生成实体类

建表

建立学生表,如下。

create table student
(
    id         int primary key auto_increment not null comment '主键',
    id_card    varchar(18)                    not null unique comment '学生身份证号',
    name       varchar(10)                    not null comment '学生姓名',
    age        int                            not null comment '学生年龄',
    enter_time datetime                       not null comment '入学时间'
);

使用flask-sqlalgencode建立model

安装

pip install flask-sqlalgencode 

使用

代码如下。

import os

connect_url = "mysql+pymysql://root:123456@localhost:3306/test"  # 使用pymysql
cmd = f'flask-sqlacodegen {connect_url} --outfile=models.py --tables student --flask'
'''
--outfile 指定输出文件
--tables 指定需要生成的表名
'''
os.popen(cmd).read()

可以看到在当前目录下,生成了一个models.py文件,其中代码如下。

# coding: utf-8
from flask_sqlalchemy import SQLAlchemy


db = SQLAlchemy()



class Student(db.Model):
    __tablename__ = 'student'

    id = db.Column(db.Integer, primary_key=True, info='主键')
    id_card = db.Column(db.String(18), nullable=False, unique=True, info='学生身份证号')
    name = db.Column(db.String(10), nullable=False, info='学生姓名')
    age = db.Column(db.Integer, nullable=False, info='学生年龄')
    enter_time = db.Column(db.DateTime, nullable=False, info='入学时间')

思考

获取表的信息

可以使用sqlalchemy的inspect模块中的方法

from sqlalchemy import create_engine,inspect

engine = create_engine("mysql+pymysql://root:123456@localhost:3306/test")
insp = inspect(engine)
a=insp.get_columns('student')
for i in a:
    print(i)

打印的结果如下

{'name': 'id', 'type': INTEGER(), 'default': None, 'comment': '主键', 'nullable': False, 'autoincrement': True}
{'name': 'id_card', 'type': VARCHAR(length=18), 'default': None, 'comment': '学生身份证号', 'nullable': False}
{'name': 'name', 'type': VARCHAR(length=10), 'default': None, 'comment': '学生姓名', 'nullable': False}
{'name': 'age', 'type': INTEGER(), 'default': None, 'comment': '学生年龄', 'nullable': False, 'autoincrement': False}
{'name': 'enter_time', 'type': DATETIME(), 'default': None, 'comment': '入学时间', 'nullable': False}

表的信息和flask-sqlalcodegen生成的信息很多相似的,经过观察和分析。

可以得出结论

提取表中的信息

上面已经可以获取表的信息,现在就是提取表的信息,为了和sqlalcodegen生成的代码接近,笔者的代码如下。

from sqlalchemy import create_engine, inspect


def get_table_info(table_name):
    """
    获取表字段
    :param table_name: 表名
    :return: 字段列表
    """
    engine = create_engine("mysql+pymysql://root:123456@localhost:3306/test")
    insp = inspect(engine)
    table_info = insp.get_columns(table_name)
    columns = []
    columns_package = []
    for table in table_info:
        name = table.pop('name') + '=Column('
        column_type_name = table.get('type').__visit_name__  # 获取类型名称
        columns_package.append(column_type_name)
        for k, v in table.items():
            if k == 'comment':  # 注释加上引号
                v = '\'' + v + '\''
            if k == 'type':  # 获取类型
                property = str(v)
            else:
                property = k + '=' + str(v)  # 字符串拼接
            name += property + ', '
        column = name[:-2] + ')'  # 去掉最后的逗号,加上括号
        print(column)
        columns.append(column)
    # 去重
    columns_package = list(set(columns_package))
    return columns, columns_package


get_table_info('student')

打印的结果如下图所示。

sqlalchemy和moke生成实体类(一)-LMLPHP

看来还是可以的,虽然类型有点差别。

表的信息放入的moke的模板中

需要pip安装mako。

根据sqlalcodegen写模板,笔者使用mako作为模板库,也可以使用jinjia2,看个人喜好。

新建一个entity.txt文件,其中内容如下。

from flask_sqlalchemy import SQLAlchemy    <%packages=','.join(package)%>
from sqlalchemy import Column,${packages}
db = SQLAlchemy()
<%
tableName=table_name.capitalize()
%>
class ${tableName}Model(db.Model):
    __tablename__ = '${table_name}'
   % for column in columns:
    ${column}
   % endfor

关于mako的具体用法可以参考官网。

welcome to Mako! (makotemplates.org)

运行测试

运行的代码如下。

from mako.template import Template
from sqlalchemy import create_engine, inspect


def get_table_info(table_name):
    """
    获取表字段
    :param table_name: 表名
    :return: 字段列表
    """
    engine = create_engine("mysql+pymysql://root:123456@localhost:3306/test")
    insp = inspect(engine)
    table_info = insp.get_columns(table_name)
    columns = []
    columns_package = []
    for table in table_info:
        name = table.pop('name') + '=Column('
        column_type_name = table.get('type').__visit_name__  # 获取类型名称
        columns_package.append(column_type_name)
        for k, v in table.items():
            if k == 'comment':  # 注释加上引号
                v = '\'' + v + '\''
            if k == 'type':  # 获取类型
                property = str(v)
            else:
                property = k + '=' + str(v)  # 字符串拼接
            name += property + ', '
        column = name[:-2] + ')'  # 去掉最后的逗号,加上括号
        columns.append(column)
    columns_package = list(set(columns_package))
    return columns, columns_package



template=Template(filename='entity.txt')
columns,package=get_table_info('student')
print(template.render(table_name='student', columns=columns, package=package))

结果如下。

from flask_sqlalchemy import SQLAlchemy    
from sqlalchemy import Column,INTEGER,DATETIME,VARCHAR
db = SQLAlchemy()

class StudentModel(db.Model):
    __tablename__ = 'student'
    id=Column(INTEGER, default=None, comment='主键', nullable=False, autoincrement=True)
    id_card=Column(VARCHAR(18), default=None, comment='学生身份证号', nullable=False)
    name=Column(VARCHAR(10), default=None, comment='学生姓名', nullable=False)
    age=Column(INTEGER, default=None, comment='学生年龄', nullable=False, autoincrement=False)
    enter_time=Column(DATETIME, default=None, comment='入学时间', nullable=False)

 不知道有没有bug,很有可能问题,以后再修改。

03-24 11:11