vue-element-admin+flask实现数据查询项目

2023-11-16

本文分享一个使用vue-element-admin+flask实现的一个数据查询项目,

填写数据库连接信息和查询语句,即可展示查询到的数据。

 

前提:已下载vue-element-admin并编译成功

前端

1、添加路由

src-router-index.js添加路由

{
    path: '/idata',
    component: Layout,
    redirect: '/idata/index',
    hidden: false,
    children: [
      {
        path: 'index',
        component: () => import('@/views/idata/index'),
        name: 'idata',
        meta: { title: 'iData设置', icon: 'list', noCache: true }
      }
    ]
  },

2、添加页面元素

在src-views下新建idata目录,目录下新建index.vue

<template>
  <div class="app-container">
    <el-card class="box-card">
      <el-form :inline="true" ref="formData" :rules="rules" :model="formData" label-width="55px">
        <el-form-item label="域名" prop="db_host">
          <el-input
          v-model="formData.db_host"></el-input>
        </el-form-item>
        <el-form-item label="端口" prop="db_port" >
          <el-input
          v-model="formData.db_port" style="width: 80px;"></el-input>
        </el-form-item>
        <el-form-item label="用户名" prop="db_user">
          <el-input
          v-model="formData.db_user" style="width: 80px;"></el-input>
        </el-form-item>
        <el-form-item label="密码" prop="db_passwd">
          <el-input
          v-model="formData.db_passwd" show-password></el-input>
        </el-form-item>
        <el-form-item label="数据库" prop="db_name">
          <el-input
          v-model="formData.db_name"></el-input>
        </el-form-item>
       
  
          <el-row>
      <el-input
        type="textarea"
        :rows="5"
        placeholder="请输入SQL语句"
        v-model="formData.sql">
      </el-input>
    </el-row>
  <el-row>
          <el-button type="primary" @click="onConnect('formData')">测试连接</el-button>
          <el-button type="primary" @click="onExec('formData')">执行SQL</el-button>
          <p>{{message}}</p>
        </el-row>
    
      
    </el-form>

      
        
        
  
    </el-card>
    <el-card class="box-card">
      <el-table
      :data="tableData"
     
      style="width: 100%">
        <el-table-column v-for="h in tableHead" :key="h"
          :prop="h" :label="h">
        </el-table-column>
      </el-table>
    </el-card>
  </div>
</template>

<script>
import { getConnect, doConnect, exec } from '@/api/idata'
export default {
  name: 'idata',
  data() {
    return {
      rules: {
        db_host: [
          { required: true, message: '请输入域名', trigger: 'blur' }
        ],
        db_port: [
          { required: true, message: '请输入端口', trigger: 'blur' }
        ],
        db_user: [
          { required: true, message: '请输入用户名', trigger: 'blur' }
        ],
        db_passwd: [
          { required: true, message: '请输入密码', trigger: 'blur' }
        ],
        db_name: [
          { required: true, message: '请输入数据库', trigger: 'blur' }
        ]
      },

      title: 'iData设置',
      formData: {
        db_charset: 'utf8',
        db_host: null,
        db_port: null,
        db_user: null,
        db_passwd: null,
        db_name: null,
        sql: null,
        param: {},
        key: 'all'
      },
      tableData: [],
      time: 0,
      uniqKey: null,
      maxCount: 20,
      sql: null,
      message:null,
      tableHead: [],
      result:[]
    }
  },
  methods: {
    onConnect (formName) {
        this.$refs[formName].validate((valid) =>{
        if (valid) {
        
         doConnect({
        ...this.formData
      }).then(res => {
        
        this.uniqKey = res.uniq_key
        this.message='连接成功'
        this.$message({
          message: '连接测试成功!',
          type: 'success'
        })
      })
          }
         else {    
          this.$message({
            message: '请检查必填字段!',
            type: 'error'
          })
           
            return false
          }
      }
      )//验证函数结尾
    },
    onExec (formName) {
      this.$refs[formName].validate((valid) =>{
      if (valid) {
          if (!this.formData.sql) {
            this.$message({
              message: 'SQL 语句不能为空。',
              type: 'warning'
            })
            return
          }
      
      exec({                      
            ...this.formData,           
           
          }).then(res => {
           
              if (res.data.length > 0) {  
              this.tableHead = []
              for (let i in res.data[0]) {
                this.tableHead.push(i)
              }
              this.tableData = res.data  
              this.time = res.time_cost
            } else {                      
              this.tableHead = []
              this.tableData = []
            }
            this.message='查询成功'
            this.loading = false
            this.$message({
              message: '查询成功',
              type: 'success'
            }

            )
         
       
  }
           ).catch(err => { 
            this.loading = false
            console.log(err)
            this.$message({
            
              type: 'error'
            })
          })
        }
       else {    
        this.$message({
          message: '请检查必填字段!',
          type: 'error'
        })
          console.log('error submit!!')
          return false
        }
    }
    )//验证函数结尾
  }//onconnect函数结尾
}
}
</script>

3、添加请求

在src-api新建idata.js

import request from '@/utils/request'


export function doConnect (data) {
  return request({
    url: '/api/test',
    method: 'post',
    data
  })
}

export function exec (data) {
  return request({
    url: '/api/idata',
    method: 'post',
    data
  })
}

----拿到ret结果,根据结果来显示默认按钮/成功按钮。
----如何展示查询到的数据呢? 前端实际有一个table,动态读取结果字段显示。
----查询数据时,前端一直报错,显示error,控制台显示uncanght promise报错。
查了一会,才发现是后端返回的ret没有code这个字段,加上就可以了。
----如何将textraea输入框宽度增加
----弹框消息
  this.$message({
          message: '连接测试成功!',
          type: 'success'
        })
----前端方法里的response.data实际是取的返回结果data这个key的值
---- this.$refs 用来给标签或者组件添加属性。需要这个标签或者组件中有ref=
 <el-form  :inline="true"  ref="formData" :rules="rules" :model="formData"
label-width="70px">
----控制台可以调试前端代码
-----form加:rules="rules" 并且在return里写上规则,并且每个el-form-item要有prop,可以实现
校验必填 其实在el-form这个组件有写对于表单的校验
-----加了校验后报错 Cannot read properties of undefined (reading 'validate')
传参需要加引号submit('formName')。
 this.$refs[formName].validate 这一行是对的

 

后端

这里只贴主要代码,有时间再继续贴。

1、添加路由

app.py添加

 app.route('/api/idata', methods=['POST'])(idata)
    app.route('/api/test',methods=['POST'])(onconnect)

2、添加函数

controller下data.py

import json
from flask import request, current_app as app
from constant import SQLTYPE, DBKEYTYPE
from lib.dbpool import DBPool


def idata():
    return query(request.json)

def onconnect():
    data=request.json
    conn_info = warp_db_conn_info(data)
    print(conn_info)
    db_conn = DBPool.get_conn(**conn_info)
    ret = {
        "success": False,
        "msg": None,
        'code':0
    }
    if not db_conn:
        ret['msg'] = '连接目标DB失败,请确认连接信息是否正确'
        ret['code']=-1
    else:
        ret['msg'] = '连接成功'
        ret['success']=True
        ret['code']=0
    return ret


def warp_db_conn_info(data):
    d = {}
    keys = ['db_host', 'db_port', 'db_name', 'db_user', 'db_passwd', 'db_charset']
    for key in keys:
        if key in data and data[key]:
            d[key] = data[key].strip() if isinstance(data[key], (str, bytes)) else data[key]

    return d


def query(data):
    """
    根据DB和SQL信息执行远程查询并返回结果
    :param data:     {
        "db_host": "x.x.x.x",
        "db_port": 3306,
        "db_name": "test",
        "db_user": "root",
        "db_passwd": "root",
        "db_charset": "utf8",
        "sql": "select * from tbl_key_info where id=:id limit 1",
        "param": {
            "id": 100110
        },
        "key": "all"
    }
    :return: {
        "success": True,
        "data": [{"id": 100110, "xxx", "xxx"}],
        "type": "SELECT",
        "msg": ""
    }
    """
    app.logger.info(f'query data {json.dumps(data)}')
    ret = {
        "success": False,
        "data": [],
        "type": None,
        "msg": None,
        "code":0
    }

    if not data:
        return ret

    conn_info = warp_db_conn_info(data)
    # print(conn_info)
    db_conn = DBPool.get_conn(**conn_info)
    if not db_conn:
        ret['msg'] = '连接目标DB失败,请确认连接信息是否正确'
        return ret

    sql = data.get('sql')
    if not sql:
        ret['msg'] = '查询语句不能为空'
        return ret

    # app.logger.info(f'查询语句: {sql}, 查询参数: {data.get("param")}')
    app.logger.info(f'查询语句: {sql}, 查询参数: {data.get("param")}')
    # rows = db_conn.query(sql, **data.get('param'))
    rows = db_conn.query(sql)
    results = []

    upper_sql = sql.upper().strip()
    if upper_sql.startswith(SQLTYPE.INSERT):
        sql_type = SQLTYPE.INSERT
    elif upper_sql.startswith(SQLTYPE.UPDATE):
        sql_type = SQLTYPE.UPDATE
    elif upper_sql.startswith(SQLTYPE.DELETE):
        sql_type = SQLTYPE.DELETE
    elif upper_sql.startswith(SQLTYPE.SELECT):
        sql_type = SQLTYPE.SELECT
        key = data.get('key', DBKEYTYPE.FIRST)
        if key == 'all':
            results = rows.as_dict()
        else:  # 为了减少网络传输,默认只查询一行
            first = rows.first()
            results = [first.as_dict()] if first else []
    else:
        sql_type = SQLTYPE.UNKNOWN

    ret.update(
        {
            "success": True,
            "data": results,
            "type": sql_type,
            "msg": '',
            'code':0

        }
    )

    app.logger.info(f'查询结果: {results}')
    return ret

dbpool.py用来进行数据库连接

import records
from urllib import parse


class DBPool:
    db_pool = {}

    @staticmethod
    def get_conn(db_host=None, db_name=None, db_port="3306", db_user='root',
                 db_passwd='root', db_charset='utf8'):
        if db_host is None or db_name is None:
            raise ValueError("host and db_name can't be None.")

        key = DBPool.make_uniq_key(db_host, db_port, db_name)
        if key not in DBPool.db_pool:
            sql_str = DBPool.make_conn_str(db_host, db_name, db_port, db_user, db_passwd, db_charset)
            print(sql_str)
            DBPool.db_pool[key] = records.Database(sql_str, pool_pre_ping=True)

        try:
            db = DBPool.db_pool[key]
            db.query('''select 1''')
        except:
            db = None
            del DBPool.db_pool[key]

        return db

    @staticmethod
    def make_uniq_key(db_host, db_name, db_port):
        return f'{db_host}:{db_port}:{db_name}'

    @staticmethod
    def make_conn_str(db_host, db_name, db_port, db_user, db_passwd, db_charset):
        return f'mysql+pymysql://{db_user}:{parse.quote_plus(db_passwd)}@{db_host}:{db_port}/{db_name}?charset={db_charset}'

今天晚了,改天有时间再详细讲解。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue-element-admin+flask实现数据查询项目 的相关文章

随机推荐

  • JDK1.8 下载与安装

    JDK安装 JDK1 8下载 下载链接 https www oracle com java technologies javase javase jdk8 downloads html 根据操作系统版本下载 这里以win10 64位操作系统
  • 驱动程序里ioctl下switch问题

    今天在写步进电机驱动程序时 switch语句引出3个分支 case 0 case 1 case 2 case 0 什么都不做 case 1让步进电机正向转动 case 2让步进电机反向转动 但是测试时 case 2怎么也动不起来 后来把ca
  • PLSQL Developer的配置方法

    1 下载32位的版本instantclient basic nt 11 2 0 3 0 zip 因为PLSQLDev是32位的 没有64位的版本 这 个和操作系统无关 2 instantclient下载完后是一个压缩文件 不需要安装 配置一
  • 服务器系统如何清理,服务器清理内存怎么清理

    服务器清理内存怎么清理 内容精选 换一换 本节操作指导您完成Windows操作系统云服务器磁盘空间清理 弹性云服务器匀出一部分磁盘空间来充当内存使用 当内存耗尽时 云服务器可以使用虚拟内存来缓解内存的紧张 但当内存使用率已经非常高时 频繁的
  • 关于HTTP协议,一篇就够了

    HTTP简介 HTTP协议是Hyper Text Transfer Protocol 超文本传输协议 的缩写 是用于从万维网 WWW World Wide Web 服务器传输超文本到本地浏览器的传送协议 HTTP是一个基于TCP IP通信协
  • TCP 连接管理机制(一)——TCP三次握手详解 + 为什么要有三次握手

    TCP是面向连接的协议 在通信之前需要先建立连接 其本质就是打开一个socket文件 这个文件有自己的缓冲区 如果要发送数据 上层把数据拷贝到发送缓冲区 如果是接收数据 OS直接把来自网络的数据拷贝到接收缓冲区里 那么三次握手期间 Serv
  • youversion.com的圣经无法使用、无法连接、无法下载离线版本的解决方法

    最近 youversion com的圣经无法使用 无法连接 无法下载离线版本了 这是一部很好用的圣经软件 以前一直用着 后来ipad越狱重新安装的时候就不能连接了 后来无意间发现原来是这个网站被和谐了 至于GCD为什么这么做 以咱的智商尚不
  • 接口自动化测试须知

    一 做接口测试需要哪些技能 做接口测试 需要的技能 基本就是以下几点 业务流 了解系统及内部各个组件之间的业务逻辑交互 数据流 了解接口的I O input output 输入输出 协议 包括http协议 TCP IP协议族 http协议
  • CMD查杀端口的两种方式

    第一种 netstat ano windows r输入cmd并打开 输入netstat ano 记住对应的6052 输入杀掉端口 taskkill pid 6052 f 第二种 netstat aon findstr 8080 直接输入ne
  • Win10 + VS2017 + Ceres配置

    前言 Ceres是google出品的一款基于C 的开源非线性优化库 官方文档 Ceres官方文档地址 依赖库 Eigen 官网 glog github gflags github Ceres github 配置过程 1 Eigen Eige
  • Python3 爬虫 requests+BeautifulSoup4(BS4) 爬取小说网站数据

    刚学Python爬虫不久 迫不及待的找了一个网站练手 新笔趣阁 一个小说网站 前提准备 安装Python以及必要的模块 requests bs4 不了解requests和bs4的同学可以去官网看个大概之后再回来看教程 爬虫思路 刚开始写爬虫
  • GPT专业应用:快速生成职位描述(JD)

    正文共 814 字 阅读大约需要 3 分钟 人力资源必备技巧 您将在3分钟后获得以下超能力 快速生成职位描述 Beezy评级 B级 经过简单的寻找 大部分人能立刻掌握 主要节省时间 推荐人 Kim 编辑者 Linda 图片由 Lexica
  • 数据中台与传统大数据平台有什么区别?_光点科技

    一 数据中台 数据中台是聚合和治理跨域数据 将数据抽象封装成服务 提供给前台以业务价值的逻辑概念 数据中台是在平台概念上的升级 不再单纯的将功能进行大杂烩 理念上 中台有几个特点 第一 更强调数据集中存储 统一管理 提供标准化的服务 第二
  • 【毕业设计】基于springboot + vue微信小程序商城

    目录 前言 创新点 亮点 毕设目录 一 视频展示 二 系统介绍 三 项目地址 四 运行环境 五 设计模块 前台 后台 六 系统功能模块结构图 数据库设计 七 准备阶段 使用真实支付 使用模拟支付 八 使用说明 九 登录后台 十 后台页面展示
  • 前端常用工具库方法整理

    欢迎点击领取 前端面试题进阶指南 前端登顶之巅 最全面的前端知识点梳理总结 前言 在闲余的时间整理一份我们可能用到的前端工具库方法 依赖库 名称 cropperjs 图片裁剪 exif js lrz 图片旋转问题 html2canvas d
  • React性能优化(完整版)

    我的博客 http wangxince site my demo markdown React 性能优化 1 减少 render 次数 shouldComponentUpdate PureComponent shouldComponentU
  • 计算机学习三宗罪——计算机达人成长之路(3)(转载自朱云翔老师笔记)

    以计算机学习不可浮躁 只有用心学习 深挖知识 才能基础扎实 才可以深入理解计算机专业知识 从而达到 他强由他强 清风拂山岗 他横由他横 明月照大江 的境界 万变不离其宗 编程程序具有三重境界 同样以VCD播放器为例 第一重境界就如同上面的同
  • 【译】用 `Wasmer` 进行插件开发 1

    译 用 Wasmer 进行插件开发 1 Using Wasmer for Plugins Part 1 译文 原文链接 https wiredforge com blog wasmer plugin pt 1 index html 原文 G
  • 05-BTC-网络

    目录 前言 比特币网络的工作原理 比特币网络 比特币网络中的每一个节点维护一个零度节点的集合 比特币系统中 每个节点要维护一个等待上链的交易的集合 比特币网络的传播属于best effort 前言 学习肖臻老师的 区块链技术与应用 公开课笔
  • vue-element-admin+flask实现数据查询项目

    本文分享一个使用vue element admin flask实现的一个数据查询项目 填写数据库连接信息和查询语句 即可展示查询到的数据 前提 已下载vue element admin并编译成功 前端 1 添加路由 src router i