前言
如果通过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 osconnect_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 SQLAlchemydb = 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,inspectengine = 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生成的信息很多相似的,经过观察和分析。
可以得出结论
对于打印出的表的信息的字典来说
name作为属性
其他作为Column对象中的属性
提取表中的信息
上面已经可以获取表的信息,现在就是提取表的信息,为了和sqlalcodegen生成的代码接近,笔者的代码如下。
from sqlalchemy import create_engine, inspectdef 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_packageget_table_info('student')
打印的结果如下图所示。
看来还是可以的,虽然类型有点差别。
表的信息放入的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, inspectdef 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_packagetemplate=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,很有可能问题,以后再修改。