基于Flask和PostgreSQL的动态数据同步与管理工具

引言

在当今数据驱动的时代,高效管理和同步数据变得尤为重要。本文档详细介绍一个结合了Flask框架和PostgreSQL数据库的动态数据同步与管理工具。该工具支持通过Flask Web界面上传Excel文件、查看数据库中的数据、下载数据到Excel文件以及删除特定行或所有数据。此外,该工具采用了JWT进行用户身份验证,确保了数据的安全性。

主要功能

  1. 动态数据同步

    • 支持通过上传Excel文件将数据同步到PostgreSQL数据库。
    • 自动创建表(如果表不存在)并插入数据。
  2. 数据管理

    • 支持通过Web界面查看数据库中的数据。
    • 支持通过Web界面下载数据库中的数据到Excel文件。
    • 支持通过Web界面删除特定行或所有数据。
  3. 用户身份验证(JWT)

    • 通过JWT进行用户身份验证,确保API的安全性。
  4. 错误处理

    • 包含基本的错误处理机制,确保API的稳定运行。
  5. 跨域支持(CORS)

    • 支持跨域请求,便于前后端分离开发。

技术栈

  • Flask:轻量级Web应用框架,用于构建API。
  • Flask-JWT-Extended:用于JWT身份验证和授权。
  • SQLAlchemy:ORM(对象关系映射)工具,简化了数据库操作。
  • PostgreSQL:强大的开源关系型数据库,支持丰富的查询功能。
  • pandas:用于数据处理和分析。
  • psycopg2:用于连接和操作PostgreSQL数据库。
  • CORS:跨域资源共享,支持前后端分离开发。

代码结构

1. 导入模块

from flask import Flask, render_template, request, redirect, url_for, send_file, jsonify, session, flash
import pandas as pd
from sqlalchemy import create_engine
from sqlalchemy import Table, Column, Integer, Text, String, MetaData
from sqlalchemy.pool import QueuePool
import configparser
import os
import psycopg2
import io

CopyInsert

2. 初始化Flask应用

app = Flask(__name__)
app.secret_key = '1234567890'  # 设置一个密钥用于会话加密

# 从配置文件读取数据库连接信息
config = configparser.ConfigParser()
config.read('database_config.ini')

host = config['Database']['host']
port = config['Database']['port']
user = config['Database']['user']
password = config['Database']['password']
database = config['Database']['database']

# 使用连接池创建数据库引擎
engine = create_engine(
    f'postgresql+psycopg2://{user}:{password}@{host}:{port}/{database}',
    poolclass=QueuePool
)

# 模拟用户数据库
users = {
    'admin': '1234',  # 用户名:密码
    'origin': '123456'  # 用户名:密码
}

CopyInsert

3. 路由定义

首页
@app.route('/')
def index():
    if 'username' in session:
        return render_template('index.html')
    return redirect(url_for('login'))

CopyInsert

登录
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        if username in users and users[username] == password:
            session['username'] = username
            return redirect(url_for('index'))
        else:
            flash('用户名或密码错误')
    return render_template('login.html')

CopyInsert

登出
@app.route('/logout')
def logout():
    session.pop('username', None)
    return redirect(url_for('login'))

CopyInsert

上传文件
@app.route('/upload', methods=['POST'])
def upload_file():
    if 'username' not in session:
        return redirect(url_for('login'))
    if 'file' not in request.files:
        return redirect(request.url)
    file = request.files['file']
    if file.filename == '':
        return redirect(request.url)
    if file and file.filename.endswith(('.xlsx', '.xls')):
        df = pd.read_excel(file)

        df.columns = df.columns.str.lower()  # 将列名转换为小写

        table_name = os.path.splitext(file.filename)[0].lower()  # 使用Excel文件名作为表名

        # 使用参数化查询检查表是否存在
        with psycopg2.connect(host=host, port=port, user=user, password=password, database=database) as connection:
            with connection.cursor() as cursor:
                cursor.execute("SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = %s)", (table_name,))
                table_exists = cursor

你可能感兴趣的:(flask,postgresql,python,excel)