当前位置:   article > 正文

sqlalchemy和moke生成实体类(一)_fastapi sqlalchemy 根据表生成实体

fastapi sqlalchemy 根据表生成实体

前言

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

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

使用flask-sqlalcodegen生成实体类

建表

建立学生表,如下。

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

使用flask-sqlalgencode建立model

安装

pip install flask-sqlalgencode 

使用

代码如下。

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

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

  1. # coding: utf-8
  2. from flask_sqlalchemy import SQLAlchemy
  3. db = SQLAlchemy()
  4. class Student(db.Model):
  5. __tablename__ = 'student'
  6. id = db.Column(db.Integer, primary_key=True, info='主键')
  7. id_card = db.Column(db.String(18), nullable=False, unique=True, info='学生身份证号')
  8. name = db.Column(db.String(10), nullable=False, info='学生姓名')
  9. age = db.Column(db.Integer, nullable=False, info='学生年龄')
  10. enter_time = db.Column(db.DateTime, nullable=False, info='入学时间')

思考

获取表的信息

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

  1. from sqlalchemy import create_engine,inspect
  2. engine = create_engine("mysql+pymysql://root:123456@localhost:3306/test")
  3. insp = inspect(engine)
  4. a=insp.get_columns('student')
  5. for i in a:
  6. print(i)

打印的结果如下

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

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

可以得出结论

对于打印出的表的信息的字典来说

name作为属性

其他作为Column对象中的属性

提取表中的信息

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

  1. from sqlalchemy import create_engine, inspect
  2. def get_table_info(table_name):
  3. """
  4. 获取表字段
  5. :param table_name: 表名
  6. :return: 字段列表
  7. """
  8. engine = create_engine("mysql+pymysql://root:123456@localhost:3306/test")
  9. insp = inspect(engine)
  10. table_info = insp.get_columns(table_name)
  11. columns = []
  12. columns_package = []
  13. for table in table_info:
  14. name = table.pop('name') + '=Column('
  15. column_type_name = table.get('type').__visit_name__ # 获取类型名称
  16. columns_package.append(column_type_name)
  17. for k, v in table.items():
  18. if k == 'comment': # 注释加上引号
  19. v = '\'' + v + '\''
  20. if k == 'type': # 获取类型
  21. property = str(v)
  22. else:
  23. property = k + '=' + str(v) # 字符串拼接
  24. name += property + ', '
  25. column = name[:-2] + ')' # 去掉最后的逗号,加上括号
  26. print(column)
  27. columns.append(column)
  28. # 去重
  29. columns_package = list(set(columns_package))
  30. return columns, columns_package
  31. get_table_info('student')

打印的结果如下图所示。

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

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

需要pip安装mako。

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

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

  1. from flask_sqlalchemy import SQLAlchemy <%packages=','.join(package)%>
  2. from sqlalchemy import Column,${packages}
  3. db = SQLAlchemy()
  4. <%
  5. tableName=table_name.capitalize()
  6. %>
  7. class ${tableName}Model(db.Model):
  8. __tablename__ = '${table_name}'
  9. % for column in columns:
  10. ${column}
  11. % endfor

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

welcome to Mako! (makotemplates.org)

运行测试

运行的代码如下。

  1. from mako.template import Template
  2. from sqlalchemy import create_engine, inspect
  3. def get_table_info(table_name):
  4. """
  5. 获取表字段
  6. :param table_name: 表名
  7. :return: 字段列表
  8. """
  9. engine = create_engine("mysql+pymysql://root:123456@localhost:3306/test")
  10. insp = inspect(engine)
  11. table_info = insp.get_columns(table_name)
  12. columns = []
  13. columns_package = []
  14. for table in table_info:
  15. name = table.pop('name') + '=Column('
  16. column_type_name = table.get('type').__visit_name__ # 获取类型名称
  17. columns_package.append(column_type_name)
  18. for k, v in table.items():
  19. if k == 'comment': # 注释加上引号
  20. v = '\'' + v + '\''
  21. if k == 'type': # 获取类型
  22. property = str(v)
  23. else:
  24. property = k + '=' + str(v) # 字符串拼接
  25. name += property + ', '
  26. column = name[:-2] + ')' # 去掉最后的逗号,加上括号
  27. columns.append(column)
  28. columns_package = list(set(columns_package))
  29. return columns, columns_package
  30. template=Template(filename='entity.txt')
  31. columns,package=get_table_info('student')
  32. print(template.render(table_name='student', columns=columns, package=package))

结果如下。

  1. from flask_sqlalchemy import SQLAlchemy
  2. from sqlalchemy import Column,INTEGER,DATETIME,VARCHAR
  3. db = SQLAlchemy()
  4. class StudentModel(db.Model):
  5. __tablename__ = 'student'
  6. id=Column(INTEGER, default=None, comment='主键', nullable=False, autoincrement=True)
  7. id_card=Column(VARCHAR(18), default=None, comment='学生身份证号', nullable=False)
  8. name=Column(VARCHAR(10), default=None, comment='学生姓名', nullable=False)
  9. age=Column(INTEGER, default=None, comment='学生年龄', nullable=False, autoincrement=False)
  10. enter_time=Column(DATETIME, default=None, comment='入学时间', nullable=False)

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/613193
推荐阅读
相关标签
  

闽ICP备14008679号