sqlalchemy和moke生成实体类(一)

前言

如果通过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,很有可能问题,以后再修改。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/473073.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

redis关联和非关联

1.1.2.关联和非关联 传统数据库的表与表之间往往存在关联&#xff0c;例如外键&#xff1a; 而非关系型数据库不存在关联关系&#xff0c;要维护关系要么靠代码中的业务逻辑&#xff0c;要么靠数据之间的耦合&#xff1a; {id: 1,name: "张三",orders: [{id: 1,ite…

基于Spring Boot+Vue的社区医院管理系统

末尾获取源码作者介绍&#xff1a;大家好&#xff0c;我是墨韵&#xff0c;本人4年开发经验&#xff0c;专注定制项目开发 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 目录 一、项目简介 一、研究背景 二…

BUUCTF-Misc11

[SWPU2019]神奇的二维码1 1.打开附件 2.扫码 提示这里没有flag 3.binwalk 把图片放在kali,用binwalk 发现&#xff1b;里面有好几个压缩包和一张图片 binwalk -e 分离的文件 得到以下内容 4.base64 点开总共有一个加密的图片&#xff0c;和一个加密的音频&#xff0c;还有一…

【算法】差分算法(空调)

可用于求一个数组要变为另一个数组最少要改变多少次的次数 Farmer John 的 N 头奶牛对他们牛棚的室温非常挑剔。 有些奶牛喜欢温度低一些&#xff0c;而有些奶牛则喜欢温度高一些。 Farmer John 的牛棚包含一排 N 个牛栏&#xff0c;编号为 1…N&#xff0c;每个牛栏里有一头…

(一)基于IDEA的JAVA基础3

通过之前的内容&#xff0c;我们在建好的文件夹下建一个java文件&#xff0c;我们来在IDEA中写一下之前用记事本写的helloworld&#xff0c;我们先看一下java代码的规范: 1.java程序文件名一定要有意义&#xff0c;首字母一定要大写。 2.class后面的名字:由大小写字母&#x…

Apipost数据模型上线,解决相似数据结构复用问题

在API设计和开发过程中&#xff0c;存在许多瓶颈&#xff0c;其中一个主要问题是在遇到相似数据结构的API时会产生重复性较多的工作&#xff1a;在每个API中都编写相同的数据&#xff0c;这不仅浪费时间和精力&#xff0c;还容易出错并降低API的可维护性。 为了解决这个问题&a…

【mac M3】idea删除不用或者失效的jdk

【mac M3】idea删除不用或者失效的jdk 不用&#xff08;重复&#xff09;或者失效的jdk如下&#xff1a; 重复或者已失效的JDK版本出现在下拉列表中不仅影响美观&#xff0c;也影响效率&#xff0c;删除jdk的步骤如下&#xff1a; 步骤1.点击File 步骤2.选择Project Structure…

运行jpsall脚本时报命令找不到

1、问题记录 2、解决 进入脚本文件排查问题 [rootnode01 ~]# vim /usr/local/bin/jpsall 错误原因&#xff1a;第四行本来是注释&#xff0c;没有加#&#xff0c;所以总是报这个命令没找到&#xff0c;上一次出现这个问题是因为user打错了&#xff0c;所以一定要细心检查 #…

MySQL - 单表访问

单表访问 查询方式 MySQL查询的执行方式大致分为下边两种&#xff1a; 使用全表扫描进行查询 这种执行方式很好理解&#xff0c;就是把表的每一行记录都扫一遍嘛&#xff0c;把符合搜索条件的记录加入到结果集就完了。不管是啥查询都可以使用这种方式执行&#xff0c;当然&am…

基于springboot+vue的交通管理在线服务系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

代码随想录算法训练营Day52 ||leetCode 300.最长递增子序列 || 674. 最长连续递增序列 || 718. 最长重复子数组

300.最长递增子序列 class Solution { public:int lengthOfLIS(vector<int>& nums) {if (nums.size() < 1) return nums.size();vector<int> dp(nums.size(), 1);int result 0;for (int i 1; i < nums.size(); i) {for (int j 0; j < i; j) {if (…

Jmeter的自动化测试实施方案

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号&#xff1a;互联网杂货铺&#xff0c;回复1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;薪资嘎嘎涨 Jmeter是目前最流行的一种测试工具&#xff0c;基于此…

JUnit5的条件测试、嵌套测试、重复测试

条件测试 JUnit5支持条件注解&#xff0c;根据布尔值判断是否执行测试。 自定义条件 EnabledIf和DisabledIf注解用来设置自定义条件&#xff0c;示例&#xff1a; Test EnabledIf("customCondition") void enabled() { // ... } Test DisabledIf("cust…

【干货详解】全网最全白盒测试攻略大全

白盒测试&#xff08;White Box Testing&#xff09;又称结构测试、透明盒测试、逻辑驱动测试或基于代码的测试。白盒测试只测试软件产品的内部结构和处理过程&#xff0c;而不测试软件产品的功能&#xff0c;用于纠正软件系统在描述、表示和规格上的错误&#xff0c;是进一步测…

Docker常用命令练习

文章目录 Docker常用命令练习1.docker 基础命令2.镜像命令3.保存镜像4.加载镜像5.容器命令6.环境变量7. --rm8. --networkhost Docker常用命令练习 1.docker 基础命令 安装docker yum install docker启动docker systemctl start docker关闭docker systemctl stop docker重…

外卖项目:用Redis实现缓存店铺营业状态、店铺菜品,优化商品浏览速度(debug一遍)

文章目录 一、设置店铺营业状态二、缓存菜品三、缓存套餐四、执行速度 一、设置店铺营业状态 针对店铺的营业状态&#xff0c;只涉及到一个字段&#xff0c;就没有设计表结构了&#xff0c;所有直接用redis存储来实现该功能。 约定&#xff1a;1表示营业 0表示打烊 先来看原先…

【Redis】Redis常见原理和数据结构

Redis 什么是redis redis是一款基于内存的k-v数据结构的非关系型数据库&#xff0c;读写速度非常快&#xff0c;常用于缓存&#xff0c;消息队列、分布式锁等场景。 redis的数据类型 string&#xff1a;字符串 缓存对象&#xff0c;分布式ID&#xff0c;token&#xff0c;se…

手撕算法-二叉树的最大深度

描述&#xff1a;分析&#xff1a;求以节点root为根节点的树的最大深度。可以进行拆分&#xff1a;root为根节点的树的最大深度 max(左子树的最大深度, 右子树最大深度&#xff09;1 截止条件是节点为空&#xff0c;深度为0&#xff1b; 代码&#xff1a; public int maxDep…

CAN总线协议:过载帧与帧间隔

一. 简介 通过 CAN 总线传输数据是需要按照一定协议进行的。CAN 协议提供了 5 种帧格式来传输数据&#xff1a;数据帧、遥控帧、错误帧、过载帧和帧间隔。 前面几篇文章学习了CAN协议的的三种数据传输格式&#xff1a; CAN总线协议&#xff1a;数据帧-CSDN博客 CAN总线协议…

相聚武汉氢能展_2024武汉国际氢能源及燃料电池产业博览会

相聚武汉氢能展_2024武汉国际氢能源及燃料电池产业博览会 2024武汉国际氢能源及燃料电池产业博览会 2024 Wuhan International Hydrogen Energy and Fuel Cell Industry Expo 同期举办&#xff1a;2024世界汽车制造技术暨智能装备博览会 时间&#xff1a;2024.8.14-16 地…