简介
本文档详细介绍一个结合了Flask框架、SQLAlchemy ORM以及PostgreSQL数据库的动态API项目。该API不仅支持通过GET请求查询数据库中的任意表数据,还支持调用数据库中的存储过程和函数。此外,该API采用了JWT(JSON Web Token)进行用户身份验证和授权,确保了数据的安全性。
主要功能
-
用户登录与Token获取
- 提供
/api/login
接口,用户通过POST请求提交用户名和密码,验证成功后返回一个JWT Token。
- 提供
-
动态数据查询API
/api/query_data
接口支持通过GET请求查询数据库中的任意表数据。用户可以通过查询参数指定要查询的表名、字段以及查询条件(如大于、小于、等于、包含等),并可限制查询结果的数量。
-
存储过程调用API
/api/call_stored_procedure
接口支持通过GET请求调用数据库中的存储过程。用户可以通过查询参数传递存储过程所需的参数,并接收存储过程的执行结果。
-
函数调用API
/api/call_function
接口支持通过GET请求调用数据库中的函数。用户可以通过查询参数传递函数所需的参数,并接收函数的执行结果。
技术栈
- Flask:轻量级Web应用框架,用于构建API。
- SQLAlchemy:ORM(对象关系映射)工具,简化了数据库操作。
- PostgreSQL:强大的开源关系型数据库,支持存储过程和函数。
- JWT:用于身份验证和授权。
- CORS:跨域资源共享,支持前后端分离开发。
代码结构
1. 导入模块
from flask import Flask, jsonify, request, make_response
from flask_jwt_extended import JWTManager, jwt_required, create_access_token, get_jwt_identity
from sqlalchemy.orm import declarative_base, sessionmaker
from sqlalchemy import create_engine, inspect, Column, Integer, String, DateTime
from sqlalchemy.pool import QueuePool
from sqlalchemy import text, bindparam, null
from decimal import Decimal
from datetime import datetime, date
import json
from collections import OrderedDict
import configparser
import html
import logging
import os
from flask_cors import CORS
import uuid
from sqlalchemy.exc import NoSuchTableError, StatementError
from urllib.parse import quote_plus
2. 初始化Flask应用
app = Flask(__name__)
CORS(app)
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# JWT配置
app.config['JWT_SECRET_KEY'] = os.getenv('JWT_SECRET_KEY', 'fallback-secret')
jwt = JWTManager(app)
3. 模拟用户数据库
users = {
'zhangsan': '123456',
'test': 'asdfgh'
}
4. 数据库连接配置
config = configparser.ConfigParser()
config.read('database_config.ini')
host = config['Postgres']['host']
port = config['Postgres']['port']
user = config['Postgres']['user']
password = config['Postgres']['password']
database = config['Postgres']['database']
encoded_password = quote_plus(password)
connection_string = f'postgresql+psycopg2://{user}:{encoded_password}@{host}:{port}/{database}'
engine = create_engine(connection_string, poolcl