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