主分支

This commit is contained in:
WIN-T9V3LPE8NK2\Administrator 2025-06-17 17:46:44 +08:00
commit 4911f3024f
2213 changed files with 695537 additions and 0 deletions

27
.dockerignore Normal file
View File

@ -0,0 +1,27 @@
**/__pycache__
**/.venv
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/bin
**/charts
**/docker-compose*
**/compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md

4
.env Normal file
View File

@ -0,0 +1,4 @@
DB_HOST=110.41.172.10
DB_PASSWORD=ldeSpQEL0Pbz5A61dCNb
DB_PORT=3309
DB_DATABASE=flask_dev

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
__pycache__/
*.pyc
logs
venv
data

3
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

14
.idea/huaxi.iml Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="private" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
<option name="format" value="PLAIN" />
<option name="myDocStringFormat" value="Plain" />
</component>
</module>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
.idea/misc.xml Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="private" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="private" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/huaxi.iml" filepath="$PROJECT_DIR$/.idea/huaxi.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

9
README.md Normal file
View File

@ -0,0 +1,9 @@
# My Flask App
This is a simple Flask application with a MySQL database.
## Installation
1. Clone the repository.
2. Install dependencies: `pip install -r requirements.txt`.
3. Run the application: `python run.py`.

36
app/__init__.py Normal file
View File

@ -0,0 +1,36 @@
from flask import Flask,jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate # type: ignore
from config import Config
from flask_cors import CORS
db = SQLAlchemy()
migrate = Migrate()
def create_app():
app = Flask(__name__)
CORS(app)
app.config.from_object(Config)
# 初始化数据库
db.init_app(app)
migrate.init_app(app, db)
# 添加根路由
@app.route('/')
def home():
return jsonify({"status": "success", "message": "Welcome to the API!"})
# 注册蓝图
from app.routes import session_routes, user_routes, message_routes, report_routes
# 注册路由
app.register_blueprint(session_routes)
app.register_blueprint(message_routes)
app.register_blueprint(report_routes)
app.register_blueprint(user_routes)
return app

4
app/models/__init__.py Normal file
View File

@ -0,0 +1,4 @@
from .user import User
from .session import Session
from .message import Message
from .report import Report

38
app/models/message.py Normal file
View File

@ -0,0 +1,38 @@
from datetime import datetime
from .. import db
class Message(db.Model):
__tablename__ = 'Messages'
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.String(500), nullable=True)
remark = db.Column(db.Text, nullable=True)
role = db.Column(db.String(50), nullable=False)
# # 外键字段(使用驼峰命名)
sessionId = db.Column(db.Integer, db.ForeignKey(
'Sessions.id'), nullable=False) # 外键关联 Session 表
# 通用字段
createdAt = db.Column(db.DateTime, default=datetime.now) # 创建时间
updatedAt = db.Column(db.DateTime, default=datetime.now,
onupdate=datetime.now) # 更新时间
deleteAt = db.Column(db.DateTime, default=None) # 软删除标记
session = db.relationship('Session', backref='messages')
def to_dict(self):
return {
'id': self.id,
'content': self.content,
'remark': self.remark,
'role': self.role,
# 'session': {
# "id": self.session.id,
# "name": self.session.name,
# }
}
def __repr__(self):
return f'<Message {self.content}>'

27
app/models/report.py Normal file
View File

@ -0,0 +1,27 @@
from datetime import datetime
from .. import db
class Report(db.Model):
__tablename__ = 'Reports'
id = db.Column(db.Integer, primary_key=True)
report = db.Column(db.JSON, nullable=True)
# # 外键字段(使用驼峰命名)
sessionId = db.Column(db.Integer, db.ForeignKey(
'Sessions.id'), nullable=False)
# 通用字段
createdAt = db.Column(db.DateTime, default=datetime.now) # 创建时间
updatedAt = db.Column(db.DateTime, default=datetime.now,
onupdate=datetime.now) # 更新时间
deleteAt = db.Column(db.DateTime, default=None) # 软删除标记
def to_dict(self):
return {
'id': self.id,
'report': self.report,
}
def __repr__(self):
return f'<Report {self.id}>'

36
app/models/session.py Normal file
View File

@ -0,0 +1,36 @@
from datetime import datetime
from .. import db
class Session(db.Model):
__tablename__ = 'Sessions'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=False)
# # 外键字段(使用驼峰命名)
userId = db.Column(db.Integer, db.ForeignKey(
'Users.id'), nullable=False)
# 通用字段
createdAt = db.Column(db.DateTime, default=datetime.now) # 创建时间
updatedAt = db.Column(db.DateTime, default=datetime.now,
onupdate=datetime.now) # 更新时间
deleteAt = db.Column(db.DateTime, default=None) # 软删除标记
# 定义与 User 表的关系 SQLAlchemy(ORM) 会自动处理外键关系
user = db.relationship('User', backref='sessions')
def to_dict(self):
return {
'id': self.id,
'name': self.name,
# 'user': {
# "id": self.user.id,
# "name": self.user.name,
# "email": self.user.email,
# "role": self.user.role,
# }
}
def __repr__(self):
return f'<Session {self.name}>'

29
app/models/user.py Normal file
View File

@ -0,0 +1,29 @@
from datetime import datetime
from .. import db
class User(db.Model):
__tablename__ = 'Users'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
password = db.Column(db.String(120), nullable=False)
role = db.Column(db.String(50), nullable=False) # 角色字段
# 通用字段
createdAt = db.Column(db.DateTime, default=datetime.now) # 创建时间
updatedAt = db.Column(db.DateTime, default=datetime.now,
onupdate=datetime.now) # 更新时间
deleteAt = db.Column(db.DateTime, default=None) # 软删除标记
def to_dict(self):
return {
'id': self.id,
'name': self.name,
'email': self.email,
'role': self.role
}
def __repr__(self):
return f'<User {self.name}>'

5
app/routes/__init__.py Normal file
View File

@ -0,0 +1,5 @@
# from .main_routes import main_routes # 导出新路由
from .session_routes import session_routes # 导出新路由
from .user_routes import user_routes # 导出新路由
from .message_routes import message_routes # 导出新路由
from .report_routes import report_routes # 导出新路由

1
app/routes/globals.py Normal file
View File

@ -0,0 +1 @@
consultation = None

View File

@ -0,0 +1,134 @@
from flask import Blueprint, jsonify, request
from ..models import Session, Message
from .. import db
from . import globals
import json,ast
# from .report_routes import consultation
message_routes = Blueprint('message', __name__)
def filter_data(data):
return {
"content": data.get("content"),
"remark": data.get("remark"),
"role": data.get("role"),
"sessionId": data.get("sessionId")
}
def validate_session_id(sessionId):
"""验证sessionId是否提供且存在于Session表中"""
if not sessionId:
return jsonify({"error": "sessionId is required"}), 400
session = Session.query.filter_by(id=sessionId).first()
if not session:
return jsonify({"error": "Session not found"}), 404
return None
@message_routes.route('/get-message/<int:sessionId>', methods=['GET'])
def get_message(sessionId):
"""获取当前用户的所有会话"""
validation_result = validate_session_id(sessionId)
if validation_result:
return validation_result
messages = Message.query.filter_by(sessionId=sessionId).all()
return jsonify(messages=[message.to_dict() for message in messages]), 200
@message_routes.route('/add-message', methods=['POST'])
def add_message():
"""添加会话"""
data = request.get_json()
print("22222222request",request)
result = filter_data(data)
validation_result = validate_session_id(result["sessionId"]) # 修改为字典访问方式
if validation_result:
return validation_result
if not result["role"]: # 修改为字典访问方式
return jsonify({"error": "role is required"}), 400
new_message = Message(**result)
db.session.add(new_message)
db.session.commit()
return jsonify({'message': 'message added successfully', 'data': new_message.to_dict()}), 201
@message_routes.route('/update-message/<int:messageId>/<int:sessionId>', methods=['PUT'])
def update_message(messageId, sessionId):
"""更新会话"""
print("1111111111111111111request",request)
data = request.get_json()
remark = data.get("remark") # 修改为字典访问方式
validation_result = validate_session_id(sessionId) # 修改为字典访问方式
if validation_result:
return validation_result # 修改为字典访问方式
message = Message.query.filter_by(id=messageId).first() # 修改为字典访问方式
if not message: # 修改为字典访问方式
return jsonify({"error": "message not found"}), 404 # 修改为字典访问方式
if remark:
message.remark = remark # 修改为字典访问方式
db.session.commit() # 修改为字典访问方式
return jsonify({'message': 'message updated successfully'})
@message_routes.route('/to-chat', methods=['POST'])
def to_chat():
print("请求头:", dict(request.headers)) # 检查Content-Type
print("原始字节数据:", request.get_data()) # 检查数据是否合法
print("1111111111111111111request",request)
# if not request.is_json:
# return jsonify({"error": "Content-Type must be application/json"}), 401
# # 2. 获取外层JSON数据
# try:
# data = request.json
# print("外层JSON数据:", data)
# except Exception as e:
# return jsonify({"error": f"外层JSON解析失败: {str(e)}"}), 402
# # 3. 解析嵌套的JSON字符串msgList和patientInfo
# try:
# # 解析msgList字符串 -> 列表)
# msg_list = json.loads(data["msgList"])
# print("解析后的msgList:", msg_list)
# # 解析patientInfo字符串 -> 字典)
# patient_info = json.loads(data["patientInfo"])
# print("解析后的patientInfo:", patient_info)
# except json.JSONDecodeError as e:
# return jsonify({"error": f"嵌套JSON解析失败: {str(e)}"}), 403
# except KeyError as e:
# return jsonify({"error": f"缺少必要字段: {str(e)}"}), 404
data = request.json
print("1111111111111111111data",data)
patientId = data['patientId']
msgList = data['msgList']
patient_info = data['patientInfo']
print("222222222patient_info",patient_info)
if len(msgList) == 0:
globals.consultation.init_session(patientId,case_data=patient_info)
content = None
else:
content = data['msgList'][-1]['content']
print("333333333content",type(content))
value, option, system = None, None, None
cur_card, answer = globals.consultation.qa_chat(patientId, content, msgList)
if cur_card and cur_card[0] and cur_card[0]['status'] == 'success':
value, option, system = cur_card[0]['option_value'], cur_card[1], cur_card[2]
return jsonify({
'answer': answer,
'analysis': {
'value': value, 'option': option, 'system': system
}
}), 201

View File

@ -0,0 +1,96 @@
import json
from flask import Blueprint, request, jsonify, g
from ..models import Session, Report
from src.main import Consultation
from src.utils import read_basic_info_json
from . import globals
from .. import db
report_routes = Blueprint('report', __name__)
def validate_session_id(sessionId):
"""验证sessionId是否提供且存在于Session表中"""
if not sessionId:
return jsonify({"error": "sessionId is required"}), 400
session = Session.query.filter_by(id=sessionId).first()
if not session:
return jsonify({"error": "Session not found"}), 404
return None
@report_routes.route('/get-report/<int:sessionId>', methods=['GET'])
def get_report(sessionId):
validation_result = validate_session_id(sessionId)
if validation_result:
return validation_result
reports = Report.query.filter_by(sessionId=sessionId).all()
return jsonify(reports=[report.to_dict() for report in reports]), 200
@report_routes.route('/add-report/<int:sessionId>', methods=['POST'])
def add_report(sessionId):
"""添加报告到数据库"""
# 获取 sessionId 和上传的文件
if not globals.consultation: # 检查是否存在consultation对象
return jsonify({"error": "No consultation object found"}), 404
if not globals.consultation.save_result: # 检查是否存在save_result方法或属性根据实际情况调整:
return jsonify({"error": "No save_result method or property found"}), 404
try:
# 验证 sessionId 是否存在
validation_result = validate_session_id(sessionId)
if validation_result:
return validation_result
report = globals.consultation.save_result(sessionId)
# 创建新的 Report 记录
new_report = Report(
sessionId=sessionId,
report=report # 假设 report_data 是 Report 表中的一个字段
)
# 添加到数据库
db.session.add(new_report)
db.session.commit()
format_report = globals.consultation.format_report(sessionId)
print(format_report,type(format_report))
return jsonify({
"message": "Report added successfully",
"data": format_report
}), 201
except json.JSONDecodeError:
return jsonify({"error": "Invalid JSON in report file"}), 400
except Exception as e:
db.session.rollback()
return jsonify({"error": f"Failed to add report: {str(e)}"}), 500
@report_routes.route('/upload-report/<int:sessionId>', methods=['POST'])
def upload_json(sessionId):
# 检查请求中是否包含文件
print(sessionId)
if 'report' not in request.files:
return jsonify({"error": "No file part"}), 400
report = request.files['report']
# 检查文件是否为空
if report.filename == '':
return jsonify({"error": "No selected file"}), 400
# 检查文件是否为 JSON 文件
if report and report.filename.endswith('.json'):
try:
# 读取文件内容并解析为 JSON
data = json.load(report)
globals.consultation.init_session(sessionId, case_data=data)
print(globals.consultation.session_map[sessionId].patient.basic_info)
return jsonify({"message": "File uploaded successfully", "data": data}), 200
except json.JSONDecodeError:
return jsonify({"error": "Invalid JSON file"}), 400
else:
return jsonify({"error": "File must be a JSON file"}), 400

View File

@ -0,0 +1,78 @@
from flask import Blueprint, jsonify, request
from ..models import Session, User
from .. import db
from . import globals
session_routes = Blueprint('session', __name__)
def validate_user_id(userId):
"""验证userId是否提供且存在于User表中"""
if not userId:
return jsonify({"error": "userId is required"}), 400
user = User.query.filter_by(id=userId).first()
if not user:
return jsonify({"error": "User not found"}), 404
return None
@session_routes.route('/get-session/<int:userId>', methods=['GET'])
def get_session(userId):
"""获取当前用户的所有会话"""
validation_result = validate_user_id(userId)
if validation_result:
return validation_result
sessions = Session.query.join(User).filter(Session.userId == userId).all()
return jsonify(sessions=[session.to_dict() for session in sessions]), 200
@session_routes.route('/add-session', methods=['POST'])
def add_session():
"""添加会话"""
data = request.get_json()
userId, name = data.get('userId'), data.get('name')
validation_result = validate_user_id(userId)
if validation_result:
return validation_result
if not name:
return jsonify({"error": "name is required"}), 400
new_session = Session(userId=userId, name=name)
db.session.add(new_session)
db.session.commit()
return jsonify({
'message': 'Session added successfully',
'data': new_session.to_dict(),
}), 201
@session_routes.route('/delete-session/<int:userId>/<int:sessionId>', methods=['DELETE'])
def delete_session(userId, sessionId):
"""删除会话"""
validation_result = validate_user_id(userId)
if validation_result:
return validation_result
session = Session.query.filter_by(
userId=userId, id=sessionId).first()
if not session:
return jsonify({"error": "Session not found"}), 404
db.session.delete(session)
db.session.commit()
return jsonify({'message': 'Session deleted successfully'})
@session_routes.route('/update-session/<int:userId>/<int:sessionId>', methods=['PUT'])
def update_session(userId, sessionId):
"""更新会话"""
data = request.get_json()
name = data.get('name')
validation_result = validate_user_id(userId)
if validation_result:
return validation_result
session = Session.query.filter_by(
userId=userId, id=sessionId).first()
if not session:
return jsonify({"error": "Session not found"}), 404
if name:
session.name = name
db.session.commit()
return jsonify({'message': 'Session updated successfully', 'session': session.to_dict()}), 200

81
app/routes/user_routes.py Normal file
View File

@ -0,0 +1,81 @@
from flask import Blueprint, jsonify, request
from ..models import User
from .. import db
user_routes = Blueprint('user', __name__)
def add_user(name, password, role, email):
"""添加新用户"""
existing_user = User.query.filter_by(email=email).first()
if existing_user:
raise ValueError("User already exists")
# 创建新用户
new_user = User(name=name, password=password, role=role, email=email)
db.session.add(new_user)
db.session.commit()
return new_user
@user_routes.route('/get-user/<int:userId>')
def get_user(userId):
"""获取单个用户"""
user = User.query.get(userId)
if user:
return jsonify(user.to_dict())
else:
return jsonify({'error': 'User not found'}), 404
@user_routes.route('/add-user', methods=['POST'])
def add_user_route():
"""添加新用户"""
data = request.get_json()
if not data or not all(key in data for key in ['name', 'email', 'password', 'role']):
return jsonify({'error': 'Invalid input'}), 400
try:
new_user = add_user(
name=data['name'],
password=data['password'],
role=data['role'],
email=data.get('email')
)
return jsonify({'message': 'User added successfully', 'user': new_user.to_dict()}), 201
except ValueError as e:
return jsonify({'error': str(e)}), 400
@user_routes.route('/delete-user/<int:userId>', methods=['DELETE'])
def delete_user(userId):
"""删除用户"""
user = User.query.get(userId)
if user:
db.session.delete(user)
db.session.commit()
return jsonify({'message': 'User deleted successfully'})
else:
return jsonify({'error': 'User not found'}), 404
@user_routes.route('/update-user/<int:userId>', methods=['PUT'])
def update_user(userId):
"""更新用户信息"""
user = User.query.get(userId)
if not user:
return jsonify({'error': 'User not found'}), 404
data = request.get_json()
if not data:
return jsonify({'error': 'Invalid input'}), 400
# 更新用户信息
user.name = data.get('name', user.name)
user.password = data.get('password', user.password)
user.role = data.get('role', user.role)
user.email = data.get('email', user.email)
db.session.commit()
return jsonify({'message': 'User updated successfully', 'user': user.to_dict()}), 200

13
config.py Normal file
View File

@ -0,0 +1,13 @@
from dotenv import load_dotenv
import os
load_dotenv()
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY') or 'your-secret-key'
# SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:first-flask@127.0.0.1:3302/flask_dev'
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:ldeSpQEL0Pbz5A61dCNb@110.41.172.10:3309/flask_dev'
# SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:{}@{}:{}/{}'.format(os.getenv(
# 'DB_PASSWORD'), os.getenv('DB_HOST'), os.getenv('DB_PORT'), os.getenv('DB_DATABASE'))
SQLALCHEMY_TRACK_MODIFICATIONS = False

16
docker-compose.yml Normal file
View File

@ -0,0 +1,16 @@
version: '3.8'
services:
mysql:
image: mysql:8.3.0
command:
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
environment:
- MYSQL_ROOT_PASSWORD=123455
- MYSQL_LOWER_CASE_TABLE_NAMES=0
ports:
- "3302:3306"
volumes:
- ./data/mysql:/var/lib/mysql

View File

@ -0,0 +1,164 @@
/* -*- indent-tabs-mode: nil; tab-width: 4; -*- */
/* Greenlet object interface */
#ifndef Py_GREENLETOBJECT_H
#define Py_GREENLETOBJECT_H
#include <Python.h>
#ifdef __cplusplus
extern "C" {
#endif
/* This is deprecated and undocumented. It does not change. */
#define GREENLET_VERSION "1.0.0"
#ifndef GREENLET_MODULE
#define implementation_ptr_t void*
#endif
typedef struct _greenlet {
PyObject_HEAD
PyObject* weakreflist;
PyObject* dict;
implementation_ptr_t pimpl;
} PyGreenlet;
#define PyGreenlet_Check(op) (op && PyObject_TypeCheck(op, &PyGreenlet_Type))
/* C API functions */
/* Total number of symbols that are exported */
#define PyGreenlet_API_pointers 12
#define PyGreenlet_Type_NUM 0
#define PyExc_GreenletError_NUM 1
#define PyExc_GreenletExit_NUM 2
#define PyGreenlet_New_NUM 3
#define PyGreenlet_GetCurrent_NUM 4
#define PyGreenlet_Throw_NUM 5
#define PyGreenlet_Switch_NUM 6
#define PyGreenlet_SetParent_NUM 7
#define PyGreenlet_MAIN_NUM 8
#define PyGreenlet_STARTED_NUM 9
#define PyGreenlet_ACTIVE_NUM 10
#define PyGreenlet_GET_PARENT_NUM 11
#ifndef GREENLET_MODULE
/* This section is used by modules that uses the greenlet C API */
static void** _PyGreenlet_API = NULL;
# define PyGreenlet_Type \
(*(PyTypeObject*)_PyGreenlet_API[PyGreenlet_Type_NUM])
# define PyExc_GreenletError \
((PyObject*)_PyGreenlet_API[PyExc_GreenletError_NUM])
# define PyExc_GreenletExit \
((PyObject*)_PyGreenlet_API[PyExc_GreenletExit_NUM])
/*
* PyGreenlet_New(PyObject *args)
*
* greenlet.greenlet(run, parent=None)
*/
# define PyGreenlet_New \
(*(PyGreenlet * (*)(PyObject * run, PyGreenlet * parent)) \
_PyGreenlet_API[PyGreenlet_New_NUM])
/*
* PyGreenlet_GetCurrent(void)
*
* greenlet.getcurrent()
*/
# define PyGreenlet_GetCurrent \
(*(PyGreenlet * (*)(void)) _PyGreenlet_API[PyGreenlet_GetCurrent_NUM])
/*
* PyGreenlet_Throw(
* PyGreenlet *greenlet,
* PyObject *typ,
* PyObject *val,
* PyObject *tb)
*
* g.throw(...)
*/
# define PyGreenlet_Throw \
(*(PyObject * (*)(PyGreenlet * self, \
PyObject * typ, \
PyObject * val, \
PyObject * tb)) \
_PyGreenlet_API[PyGreenlet_Throw_NUM])
/*
* PyGreenlet_Switch(PyGreenlet *greenlet, PyObject *args)
*
* g.switch(*args, **kwargs)
*/
# define PyGreenlet_Switch \
(*(PyObject * \
(*)(PyGreenlet * greenlet, PyObject * args, PyObject * kwargs)) \
_PyGreenlet_API[PyGreenlet_Switch_NUM])
/*
* PyGreenlet_SetParent(PyObject *greenlet, PyObject *new_parent)
*
* g.parent = new_parent
*/
# define PyGreenlet_SetParent \
(*(int (*)(PyGreenlet * greenlet, PyGreenlet * nparent)) \
_PyGreenlet_API[PyGreenlet_SetParent_NUM])
/*
* PyGreenlet_GetParent(PyObject* greenlet)
*
* return greenlet.parent;
*
* This could return NULL even if there is no exception active.
* If it does not return NULL, you are responsible for decrementing the
* reference count.
*/
# define PyGreenlet_GetParent \
(*(PyGreenlet* (*)(PyGreenlet*)) \
_PyGreenlet_API[PyGreenlet_GET_PARENT_NUM])
/*
* deprecated, undocumented alias.
*/
# define PyGreenlet_GET_PARENT PyGreenlet_GetParent
# define PyGreenlet_MAIN \
(*(int (*)(PyGreenlet*)) \
_PyGreenlet_API[PyGreenlet_MAIN_NUM])
# define PyGreenlet_STARTED \
(*(int (*)(PyGreenlet*)) \
_PyGreenlet_API[PyGreenlet_STARTED_NUM])
# define PyGreenlet_ACTIVE \
(*(int (*)(PyGreenlet*)) \
_PyGreenlet_API[PyGreenlet_ACTIVE_NUM])
/* Macro that imports greenlet and initializes C API */
/* NOTE: This has actually moved to ``greenlet._greenlet._C_API``, but we
keep the older definition to be sure older code that might have a copy of
the header still works. */
# define PyGreenlet_Import() \
{ \
_PyGreenlet_API = (void**)PyCapsule_Import("greenlet._C_API", 0); \
}
#endif /* GREENLET_MODULE */
#ifdef __cplusplus
}
#endif
#endif /* !Py_GREENLETOBJECT_H */

View File

@ -0,0 +1 @@
pip

View File

@ -0,0 +1,28 @@
Copyright 2010 Pallets
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,124 @@
Metadata-Version: 2.1
Name: Flask
Version: 2.0.1
Summary: A simple framework for building complex web applications.
Home-page: https://palletsprojects.com/p/flask
Author: Armin Ronacher
Author-email: armin.ronacher@active-4.com
Maintainer: Pallets
Maintainer-email: contact@palletsprojects.com
License: BSD-3-Clause
Project-URL: Donate, https://palletsprojects.com/donate
Project-URL: Documentation, https://flask.palletsprojects.com/
Project-URL: Changes, https://flask.palletsprojects.com/changes/
Project-URL: Source Code, https://github.com/pallets/flask/
Project-URL: Issue Tracker, https://github.com/pallets/flask/issues/
Project-URL: Twitter, https://twitter.com/PalletsTeam
Project-URL: Chat, https://discord.gg/pallets
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Framework :: Flask
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Requires-Python: >=3.6
Description-Content-Type: text/x-rst
Requires-Dist: Werkzeug (>=2.0)
Requires-Dist: Jinja2 (>=3.0)
Requires-Dist: itsdangerous (>=2.0)
Requires-Dist: click (>=7.1.2)
Provides-Extra: async
Requires-Dist: asgiref (>=3.2) ; extra == 'async'
Provides-Extra: dotenv
Requires-Dist: python-dotenv ; extra == 'dotenv'
Flask
=====
Flask is a lightweight `WSGI`_ web application framework. It is designed
to make getting started quick and easy, with the ability to scale up to
complex applications. It began as a simple wrapper around `Werkzeug`_
and `Jinja`_ and has become one of the most popular Python web
application frameworks.
Flask offers suggestions, but doesn't enforce any dependencies or
project layout. It is up to the developer to choose the tools and
libraries they want to use. There are many extensions provided by the
community that make adding new functionality easy.
.. _WSGI: https://wsgi.readthedocs.io/
.. _Werkzeug: https://werkzeug.palletsprojects.com/
.. _Jinja: https://jinja.palletsprojects.com/
Installing
----------
Install and update using `pip`_:
.. code-block:: text
$ pip install -U Flask
.. _pip: https://pip.pypa.io/en/stable/quickstart/
A Simple Example
----------------
.. code-block:: python
# save this as app.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello, World!"
.. code-block:: text
$ flask run
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Contributing
------------
For guidance on setting up a development environment and how to make a
contribution to Flask, see the `contributing guidelines`_.
.. _contributing guidelines: https://github.com/pallets/flask/blob/main/CONTRIBUTING.rst
Donate
------
The Pallets organization develops and supports Flask and the libraries
it uses. In order to grow the community of contributors and users, and
allow the maintainers to devote more time to the projects, `please
donate today`_.
.. _please donate today: https://palletsprojects.com/donate
Links
-----
- Documentation: https://flask.palletsprojects.com/
- Changes: https://flask.palletsprojects.com/changes/
- PyPI Releases: https://pypi.org/project/Flask/
- Source Code: https://github.com/pallets/flask/
- Issue Tracker: https://github.com/pallets/flask/issues/
- Website: https://palletsprojects.com/p/flask/
- Twitter: https://twitter.com/PalletsTeam
- Chat: https://discord.gg/pallets

View File

@ -0,0 +1,52 @@
../../Scripts/flask.exe,sha256=lBUblgThia4HA1tEbSUZefcCMK4F4nb8Kt33gTj3AI0,98169
Flask-2.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
Flask-2.0.1.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475
Flask-2.0.1.dist-info/METADATA,sha256=50Jm1647RKw98p4RF64bCqRh0wajk-n3hQ7av2-pniA,3808
Flask-2.0.1.dist-info/RECORD,,
Flask-2.0.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
Flask-2.0.1.dist-info/WHEEL,sha256=OqRkF0eY5GHssMorFjlbTIq072vpHpF60fIQA6lS9xA,92
Flask-2.0.1.dist-info/entry_points.txt,sha256=gBLA1aKg0OYR8AhbAfg8lnburHtKcgJLDU52BBctN0k,42
Flask-2.0.1.dist-info/top_level.txt,sha256=dvi65F6AeGWVU0TBpYiC04yM60-FX1gJFkK31IKQr5c,6
flask/__init__.py,sha256=w5v6GCNm8eLDMNWqs2ue7HLHo75aslAwz1h3k3YO9HY,2251
flask/__main__.py,sha256=bYt9eEaoRQWdejEHFD8REx9jxVEdZptECFsV7F49Ink,30
flask/__pycache__/__init__.cpython-38.pyc,,
flask/__pycache__/__main__.cpython-38.pyc,,
flask/__pycache__/app.cpython-38.pyc,,
flask/__pycache__/blueprints.cpython-38.pyc,,
flask/__pycache__/cli.cpython-38.pyc,,
flask/__pycache__/config.cpython-38.pyc,,
flask/__pycache__/ctx.cpython-38.pyc,,
flask/__pycache__/debughelpers.cpython-38.pyc,,
flask/__pycache__/globals.cpython-38.pyc,,
flask/__pycache__/helpers.cpython-38.pyc,,
flask/__pycache__/logging.cpython-38.pyc,,
flask/__pycache__/scaffold.cpython-38.pyc,,
flask/__pycache__/sessions.cpython-38.pyc,,
flask/__pycache__/signals.cpython-38.pyc,,
flask/__pycache__/templating.cpython-38.pyc,,
flask/__pycache__/testing.cpython-38.pyc,,
flask/__pycache__/typing.cpython-38.pyc,,
flask/__pycache__/views.cpython-38.pyc,,
flask/__pycache__/wrappers.cpython-38.pyc,,
flask/app.py,sha256=q6lpiiWVxjljQRwjjneUBpfllXYPEq0CFAUpTQ5gIeA,82376
flask/blueprints.py,sha256=OjI-dkwx96ZNMUGDDFMKzgcpUJf240WRuMlHkmgI1Lc,23541
flask/cli.py,sha256=iN1pL2SevE5Nmvey-0WwnxG3nipZXIiE__Ed4lx3IuM,32036
flask/config.py,sha256=jj_7JGen_kYuTlKrx8ZPBsZddb8mihC0ODg4gcjXBX8,11068
flask/ctx.py,sha256=EM3W0v1ctuFQAGk_HWtQdoJEg_r2f5Le4xcmElxFwwk,17428
flask/debughelpers.py,sha256=wk5HtLwENsQ4e8tkxfBn6ykUeVRDuMbQCKgtEVe6jxk,6171
flask/globals.py,sha256=cWd-R2hUH3VqPhnmQNww892tQS6Yjqg_wg8UvW1M7NM,1723
flask/helpers.py,sha256=00WqA3wYeyjMrnAOPZTUyrnUf7H8ik3CVT0kqGl_qjk,30589
flask/json/__init__.py,sha256=d-db2DJMASq0G7CI-JvobehRE1asNRGX1rIDQ1GF9WM,11580
flask/json/__pycache__/__init__.cpython-38.pyc,,
flask/json/__pycache__/tag.cpython-38.pyc,,
flask/json/tag.py,sha256=fys3HBLssWHuMAIJuTcf2K0bCtosePBKXIWASZEEjnU,8857
flask/logging.py,sha256=1o_hirVGqdj7SBdETnhX7IAjklG89RXlrwz_2CjzQQE,2273
flask/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
flask/scaffold.py,sha256=EhQuiFrdcmJHxqPGQkEpqLsEUZ7ULZD0rtED2NrduvM,32400
flask/sessions.py,sha256=Kb7zY4qBIOU2cw1xM5mQ_KmgYUBDFbUYWjlkq0EFYis,15189
flask/signals.py,sha256=HQWgBEXlrLbHwLBoWqAStJKcN-rsB1_AMO8-VZ7LDOo,2126
flask/templating.py,sha256=l96VD39JQ0nue4Bcj7wZ4-FWWs-ppLxvgBCpwDQ4KAk,5626
flask/testing.py,sha256=OsHT-2B70abWH3ulY9IbhLchXIeyj3L-cfcDa88wv5E,10281
flask/typing.py,sha256=zVqhz53KklncAv-WxbpxGZfaRGOqeWAsLdP1tTMaCuE,1684
flask/views.py,sha256=F2PpWPloe4x0906IUjnPcsOqg5YvmQIfk07_lFeAD4s,5865
flask/wrappers.py,sha256=VndbHPRBSUUOejmd2Y3ydkoCVUtsS2OJIdJEVIkBVD8,5604

View File

@ -0,0 +1,5 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.36.2)
Root-Is-Purelib: true
Tag: py3-none-any

View File

@ -0,0 +1,3 @@
[console_scripts]
flask = flask.cli:main

View File

@ -0,0 +1 @@
flask

View File

@ -0,0 +1 @@
pip

View File

@ -0,0 +1,7 @@
Copyright (C) 2016 Cory Dolphin, Olin College
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,148 @@
Metadata-Version: 2.1
Name: Flask-Cors
Version: 5.0.0
Summary: A Flask extension adding a decorator for CORS support
Home-page: https://github.com/corydolphin/flask-cors
Author: Cory Dolphin
Author-email: corydolphin@gmail.com
License: MIT
Platform: any
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Software Development :: Libraries :: Python Modules
License-File: LICENSE
Requires-Dist: Flask >=0.9
Flask-CORS
==========
|Build Status| |Latest Version| |Supported Python versions|
|License|
A Flask extension for handling Cross Origin Resource Sharing (CORS), making cross-origin AJAX possible.
This package has a simple philosophy: when you want to enable CORS, you wish to enable it for all use cases on a domain.
This means no mucking around with different allowed headers, methods, etc.
By default, submission of cookies across domains is disabled due to the security implications.
Please see the documentation for how to enable credential'ed requests, and please make sure you add some sort of `CSRF <http://en.wikipedia.org/wiki/Cross-site_request_forgery>`__ protection before doing so!
Installation
------------
Install the extension with using pip, or easy\_install.
.. code:: bash
$ pip install -U flask-cors
Usage
-----
This package exposes a Flask extension which by default enables CORS support on all routes, for all origins and methods.
It allows parameterization of all CORS headers on a per-resource level.
The package also contains a decorator, for those who prefer this approach.
Simple Usage
~~~~~~~~~~~~
In the simplest case, initialize the Flask-Cors extension with default arguments in order to allow CORS for all domains on all routes.
See the full list of options in the `documentation <https://flask-cors.corydolphin.com/en/latest/api.html#extension>`__.
.. code:: python
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
@app.route("/")
def helloWorld():
return "Hello, cross-origin-world!"
Resource specific CORS
^^^^^^^^^^^^^^^^^^^^^^
Alternatively, you can specify CORS options on a resource and origin level of granularity by passing a dictionary as the `resources` option, mapping paths to a set of options.
See the full list of options in the `documentation <https://flask-cors.corydolphin.com/en/latest/api.html#extension>`__.
.. code:: python
app = Flask(__name__)
cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
@app.route("/api/v1/users")
def list_users():
return "user example"
Route specific CORS via decorator
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This extension also exposes a simple decorator to decorate flask routes with.
Simply add ``@cross_origin()`` below a call to Flask's ``@app.route(..)`` to allow CORS on a given route.
See the full list of options in the `decorator documentation <https://flask-cors.corydolphin.com/en/latest/api.html#decorator>`__.
.. code:: python
@app.route("/")
@cross_origin()
def helloWorld():
return "Hello, cross-origin-world!"
Documentation
-------------
For a full list of options, please see the full `documentation <https://flask-cors.corydolphin.com/en/latest/api.html>`__
Troubleshooting
---------------
If things aren't working as you expect, enable logging to help understand what is going on under the hood, and why.
.. code:: python
logging.getLogger('flask_cors').level = logging.DEBUG
Tests
-----
A simple set of tests is included in ``test/``.
To run, install nose, and simply invoke ``nosetests`` or ``python setup.py test`` to exercise the tests.
If nosetests does not work for you, due to it no longer working with newer python versions.
You can use pytest to run the tests instead.
Contributing
------------
Questions, comments or improvements?
Please create an issue on `Github <https://github.com/corydolphin/flask-cors>`__, tweet at `@corydolphin <https://twitter.com/corydolphin>`__ or send me an email.
I do my best to include every contribution proposed in any way that I can.
Credits
-------
This Flask extension is based upon the `Decorator for the HTTP Access Control <https://web.archive.org/web/20190128010149/http://flask.pocoo.org/snippets/56/>`__ written by Armin Ronacher.
.. |Build Status| image:: https://github.com/corydolphin/flask-cors/actions/workflows/unittests.yaml/badge.svg
:target: https://travis-ci.org/corydolphin/flask-cors
.. |Latest Version| image:: https://img.shields.io/pypi/v/Flask-Cors.svg
:target: https://pypi.python.org/pypi/Flask-Cors/
.. |Supported Python versions| image:: https://img.shields.io/pypi/pyversions/Flask-Cors.svg
:target: https://img.shields.io/pypi/pyversions/Flask-Cors.svg
.. |License| image:: http://img.shields.io/:license-mit-blue.svg
:target: https://pypi.python.org/pypi/Flask-Cors/

View File

@ -0,0 +1,17 @@
Flask_Cors-5.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
Flask_Cors-5.0.0.dist-info/LICENSE,sha256=bhob3FSDTB4HQMvOXV9vLK4chG_Sp_SCsRZJWU-vvV0,1069
Flask_Cors-5.0.0.dist-info/METADATA,sha256=V2L_s849dFlZXsOhcgXVqv5Slj_JKSVuiiuRgDOft5s,5474
Flask_Cors-5.0.0.dist-info/RECORD,,
Flask_Cors-5.0.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
Flask_Cors-5.0.0.dist-info/WHEEL,sha256=WDDPHYzpiOIm6GP1C2_8y8W6q16ICddAgOHlhTje9Qc,109
Flask_Cors-5.0.0.dist-info/top_level.txt,sha256=aWye_0QNZPp_QtPF4ZluLHqnyVLT9CPJsfiGhwqkWuo,11
flask_cors/__init__.py,sha256=wZDCvPTHspA2g1VV7KyKN7R-uCdBnirTlsCzgPDcQtI,792
flask_cors/__pycache__/__init__.cpython-38.pyc,,
flask_cors/__pycache__/core.cpython-38.pyc,,
flask_cors/__pycache__/decorator.cpython-38.pyc,,
flask_cors/__pycache__/extension.cpython-38.pyc,,
flask_cors/__pycache__/version.cpython-38.pyc,,
flask_cors/core.py,sha256=y76xxLasWTdV_3ka19IxpdJPOgROBZQZ5L8t20IjqRA,14252
flask_cors/decorator.py,sha256=BeJsyX1wYhVKWN04FAhb6z8YqffiRr7wKqwzHPap4bw,5009
flask_cors/extension.py,sha256=gzv6zWUwSDYlGHBWzMuTI_hoQ7gQmp9DlcAcrKTVHdw,8602
flask_cors/version.py,sha256=JzYPYpvaglqIJRGCDrh5-hYmXI0ISrDDed0V1QQZAGU,22

View File

@ -0,0 +1,6 @@
Wheel-Version: 1.0
Generator: setuptools (74.0.0)
Root-Is-Purelib: true
Tag: py2-none-any
Tag: py3-none-any

View File

@ -0,0 +1 @@
flask_cors

View File

@ -0,0 +1 @@
pip

View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013 Miguel Grinberg
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,29 @@
Metadata-Version: 2.1
Name: Flask-Migrate
Version: 3.0.0
Summary: SQLAlchemy database migrations for Flask applications using Alembic
Home-page: http://github.com/miguelgrinberg/flask-migrate/
Author: Miguel Grinberg
Author-email: miguelgrinberg50@gmail.com
License: MIT
Platform: any
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Dist: Flask (>=0.9)
Requires-Dist: Flask-SQLAlchemy (>=1.0)
Requires-Dist: alembic (>=0.7)
Flask-Migrate
--------------
SQLAlchemy database migrations for Flask applications using Alembic.

View File

@ -0,0 +1,22 @@
Flask_Migrate-3.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
Flask_Migrate-3.0.0.dist-info/LICENSE,sha256=kfkXGlJQvKy3Y__6tAJ8ynIp1HQfeROXhL8jZU1d-DI,1082
Flask_Migrate-3.0.0.dist-info/METADATA,sha256=GaPvZY2bzoI37dGmkUagbA-xkU_BmtYo09tJ3VM_P3o,946
Flask_Migrate-3.0.0.dist-info/RECORD,,
Flask_Migrate-3.0.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
Flask_Migrate-3.0.0.dist-info/WHEEL,sha256=Z-nyYpwrcSqxfdux5Mbn_DQ525iP7J2DG3JgGvOYyTQ,110
Flask_Migrate-3.0.0.dist-info/entry_points.txt,sha256=KIMh5vVHpfcQw9lq5G7y7cVhHgS-0DdbmIS8X7mnrzI,44
Flask_Migrate-3.0.0.dist-info/top_level.txt,sha256=jLoPgiMG6oR4ugNteXn3IHskVVIyIXVStZOVq-AWLdU,14
flask_migrate/__init__.py,sha256=2ihChFIVrfrxncvCkJIGKPInS0OZnxS7BcygDD7GjKg,8095
flask_migrate/__pycache__/__init__.cpython-38.pyc,,
flask_migrate/__pycache__/cli.cpython-38.pyc,,
flask_migrate/cli.py,sha256=WtO0gpSNSzYtGlSNcqJf6dw-69xAZ4Ezc5fC5T3bo5Q,9504
flask_migrate/templates/flask-multidb/README,sha256=MVlc9TYmr57RbhXET6QxgyCcwWP7w-vLkEsirENqiIQ,38
flask_migrate/templates/flask-multidb/__pycache__/env.cpython-38.pyc,,
flask_migrate/templates/flask-multidb/alembic.ini.mako,sha256=SjYEmJKzz6K8QfuZWtLJAJWcCKOdRbfUhsVlpgv8ock,857
flask_migrate/templates/flask-multidb/env.py,sha256=QKQwwECAUOXmIhAuz_hkF6-MGNM8HuY5KJNahq8LF-4,5428
flask_migrate/templates/flask-multidb/script.py.mako,sha256=lVwJ36kfy6N1gRW7Lepg5EjXQ6Ouar4GTSBHcHXYHbs,965
flask_migrate/templates/flask/README,sha256=MVlc9TYmr57RbhXET6QxgyCcwWP7w-vLkEsirENqiIQ,38
flask_migrate/templates/flask/__pycache__/env.cpython-38.pyc,,
flask_migrate/templates/flask/alembic.ini.mako,sha256=SjYEmJKzz6K8QfuZWtLJAJWcCKOdRbfUhsVlpgv8ock,857
flask_migrate/templates/flask/env.py,sha256=2R_hqArzjlYOr-cz_KPFTXw6ZFsx_EpfpGaKqTZsir0,2746
flask_migrate/templates/flask/script.py.mako,sha256=8_xgA-gm_OhehnO7CiIijWgnm00ZlszEHtIHrAYFJl0,494

View File

@ -0,0 +1,6 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.36.2)
Root-Is-Purelib: true
Tag: py2-none-any
Tag: py3-none-any

View File

@ -0,0 +1,3 @@
[flask.commands]
db = flask_migrate.cli:db

View File

@ -0,0 +1 @@
flask_migrate

View File

@ -0,0 +1 @@
pip

View File

@ -0,0 +1,28 @@
Copyright 2010 Pallets
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,94 @@
Metadata-Version: 2.1
Name: Flask-SQLAlchemy
Version: 2.5.1
Summary: Adds SQLAlchemy support to your Flask application.
Home-page: https://github.com/pallets/flask-sqlalchemy
Author: Armin Ronacher
Author-email: armin.ronacher@active-4.com
Maintainer: Pallets
Maintainer-email: contact@palletsprojects.com
License: BSD-3-Clause
Project-URL: Documentation, https://flask-sqlalchemy.palletsprojects.com/
Project-URL: Code, https://github.com/pallets/flask-sqlalchemy
Project-URL: Issue tracker, https://github.com/pallets/flask-sqlalchemy/issues
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >= 2.7, != 3.0.*, != 3.1.*, != 3.2.*, != 3.3.*
Requires-Dist: Flask (>=0.10)
Requires-Dist: SQLAlchemy (>=0.8.0)
Flask-SQLAlchemy
================
Flask-SQLAlchemy is an extension for `Flask`_ that adds support for
`SQLAlchemy`_ to your application. It aims to simplify using SQLAlchemy
with Flask by providing useful defaults and extra helpers that make it
easier to accomplish common tasks.
Installing
----------
Install and update using `pip`_:
.. code-block:: text
$ pip install -U Flask-SQLAlchemy
A Simple Example
----------------
.. code-block:: python
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///example.sqlite"
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String, unique=True, nullable=False)
email = db.Column(db.String, unique=True, nullable=False)
db.session.add(User(name="Flask", email="example@example.com"))
db.session.commit()
users = User.query.all()
Links
-----
- Documentation: https://flask-sqlalchemy.palletsprojects.com/
- Releases: https://pypi.org/project/Flask-SQLAlchemy/
- Code: https://github.com/pallets/flask-sqlalchemy
- Issue tracker: https://github.com/pallets/flask-sqlalchemy/issues
- Test status: https://travis-ci.org/pallets/flask-sqlalchemy
- Test coverage: https://codecov.io/gh/pallets/flask-sqlalchemy
.. _Flask: https://palletsprojects.com/p/flask/
.. _SQLAlchemy: https://www.sqlalchemy.org
.. _pip: https://pip.pypa.io/en/stable/quickstart/

View File

@ -0,0 +1,15 @@
Flask_SQLAlchemy-2.5.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
Flask_SQLAlchemy-2.5.1.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475
Flask_SQLAlchemy-2.5.1.dist-info/METADATA,sha256=vVCeMtTM_xOrUVoVyemeNaTUI5L9iXa16NsiMDDOgFU,3128
Flask_SQLAlchemy-2.5.1.dist-info/RECORD,,
Flask_SQLAlchemy-2.5.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
Flask_SQLAlchemy-2.5.1.dist-info/WHEEL,sha256=Z-nyYpwrcSqxfdux5Mbn_DQ525iP7J2DG3JgGvOYyTQ,110
Flask_SQLAlchemy-2.5.1.dist-info/top_level.txt,sha256=w2K4fNNoTh4HItoFfz2FRQShSeLcvHYrzU_sZov21QU,17
flask_sqlalchemy/__init__.py,sha256=IaupgTRkQnY05KPLYvfiNnJdrmwoyfsxaiyGtrEYfO4,40738
flask_sqlalchemy/__pycache__/__init__.cpython-38.pyc,,
flask_sqlalchemy/__pycache__/_compat.cpython-38.pyc,,
flask_sqlalchemy/__pycache__/model.cpython-38.pyc,,
flask_sqlalchemy/__pycache__/utils.cpython-38.pyc,,
flask_sqlalchemy/_compat.py,sha256=yua0ZSgVWwi56QpEgwaPInzkNQ9PFb7YQdvEk3dImXo,821
flask_sqlalchemy/model.py,sha256=bd2mIv9LA1A2MZkQObgnMUCSrxNvyqplaSkCxyxKNxY,4988
flask_sqlalchemy/utils.py,sha256=4eHqAbYElnJ3NbSAHhuINckoAHDABoxjleMJD0iKgyg,1390

View File

@ -0,0 +1,6 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.36.2)
Root-Is-Purelib: true
Tag: py2-none-any
Tag: py3-none-any

View File

@ -0,0 +1 @@
flask_sqlalchemy

View File

@ -0,0 +1 @@
pip

View File

@ -0,0 +1,19 @@
Copyright 2006-2025 the Mako authors and contributors <see AUTHORS file>.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,87 @@
Metadata-Version: 2.2
Name: Mako
Version: 1.3.9
Summary: A super-fast templating language that borrows the best ideas from the existing templating languages.
Home-page: https://www.makotemplates.org/
Author: Mike Bayer
Author-email: mike@zzzcomputing.com
License: MIT
Project-URL: Documentation, https://docs.makotemplates.org
Project-URL: Issue Tracker, https://github.com/sqlalchemy/mako
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: MIT License
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Requires-Python: >=3.8
Description-Content-Type: text/x-rst
License-File: LICENSE
Requires-Dist: MarkupSafe>=0.9.2
Provides-Extra: testing
Requires-Dist: pytest; extra == "testing"
Provides-Extra: babel
Requires-Dist: Babel; extra == "babel"
Provides-Extra: lingua
Requires-Dist: lingua; extra == "lingua"
=========================
Mako Templates for Python
=========================
Mako is a template library written in Python. It provides a familiar, non-XML
syntax which compiles into Python modules for maximum performance. Mako's
syntax and API borrows from the best ideas of many others, including Django
templates, Cheetah, Myghty, and Genshi. Conceptually, Mako is an embedded
Python (i.e. Python Server Page) language, which refines the familiar ideas
of componentized layout and inheritance to produce one of the most
straightforward and flexible models available, while also maintaining close
ties to Python calling and scoping semantics.
Nutshell
========
::
<%inherit file="base.html"/>
<%
rows = [[v for v in range(0,10)] for row in range(0,10)]
%>
<table>
% for row in rows:
${makerow(row)}
% endfor
</table>
<%def name="makerow(row)">
<tr>
% for name in row:
<td>${name}</td>\
% endfor
</tr>
</%def>
Philosophy
===========
Python is a great scripting language. Don't reinvent the wheel...your templates can handle it !
Documentation
==============
See documentation for Mako at https://docs.makotemplates.org/en/latest/
License
========
Mako is licensed under an MIT-style license (see LICENSE).
Other incorporated projects may be licensed under different licenses.
All licenses allow for non-commercial and commercial use.

View File

@ -0,0 +1,74 @@
../../Scripts/mako-render.exe,sha256=6wtV_UyHkGc0tblkNtciShDyB2udVe4FompMLPkErNw,98174
Mako-1.3.9.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
Mako-1.3.9.dist-info/LICENSE,sha256=aNcGTlPj_6jp9CCp5gS9LiBZ2cMwSS-m69TrPUgRFok,1098
Mako-1.3.9.dist-info/METADATA,sha256=gImMYAE3i8pGSGz0W39Ch2SiUkYphuu5CDwgs2cviNA,2896
Mako-1.3.9.dist-info/RECORD,,
Mako-1.3.9.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
Mako-1.3.9.dist-info/entry_points.txt,sha256=LsKkUsOsJQYbJ2M72hZCm968wi5K8Ywb5uFxCuN8Obk,512
Mako-1.3.9.dist-info/top_level.txt,sha256=LItdH8cDPetpUu8rUyBG3DObS6h9Gcpr9j_WLj2S-R0,5
mako/__init__.py,sha256=0Umu9OqA4gU1dLRLTcAPieeVTbYoSlzmUeZk9FMt0N8,242
mako/__pycache__/__init__.cpython-38.pyc,,
mako/__pycache__/_ast_util.cpython-38.pyc,,
mako/__pycache__/ast.cpython-38.pyc,,
mako/__pycache__/cache.cpython-38.pyc,,
mako/__pycache__/cmd.cpython-38.pyc,,
mako/__pycache__/codegen.cpython-38.pyc,,
mako/__pycache__/compat.cpython-38.pyc,,
mako/__pycache__/exceptions.cpython-38.pyc,,
mako/__pycache__/filters.cpython-38.pyc,,
mako/__pycache__/lexer.cpython-38.pyc,,
mako/__pycache__/lookup.cpython-38.pyc,,
mako/__pycache__/parsetree.cpython-38.pyc,,
mako/__pycache__/pygen.cpython-38.pyc,,
mako/__pycache__/pyparser.cpython-38.pyc,,
mako/__pycache__/runtime.cpython-38.pyc,,
mako/__pycache__/template.cpython-38.pyc,,
mako/__pycache__/util.cpython-38.pyc,,
mako/_ast_util.py,sha256=hCbfnnizWEa3xRCA-uVyShC2HohSpmVvexz5as_lHc8,20247
mako/ast.py,sha256=xYrdSiJFbf1CxJ9tU9pcPEWK0BYfwF2aDNDNLQG9PqQ,6642
mako/cache.py,sha256=kA6FKGl5NeTBnSTcnhoPkSaeJ0JeYpF6GM8qzEZGSts,7680
mako/cmd.py,sha256=Y2Y6VxNCYwO2Y8EXOdLTf5tpYgfdoondV6Ehlbh8a84,2813
mako/codegen.py,sha256=N49EH57CcTUfKGzI8V7GFBrAEoFhRo9lkdXBzpFYzBY,47736
mako/compat.py,sha256=owGbObdoF0C-6rCCs6Vnk3YGHv0bf0PpTja55Woxqb4,1820
mako/exceptions.py,sha256=87Djuoi1IS5zyVFml1Z5zpCP1IoI7UMOH3h4ejt3x3g,12530
mako/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
mako/ext/__pycache__/__init__.cpython-38.pyc,,
mako/ext/__pycache__/autohandler.cpython-38.pyc,,
mako/ext/__pycache__/babelplugin.cpython-38.pyc,,
mako/ext/__pycache__/beaker_cache.cpython-38.pyc,,
mako/ext/__pycache__/extract.cpython-38.pyc,,
mako/ext/__pycache__/linguaplugin.cpython-38.pyc,,
mako/ext/__pycache__/preprocessors.cpython-38.pyc,,
mako/ext/__pycache__/pygmentplugin.cpython-38.pyc,,
mako/ext/__pycache__/turbogears.cpython-38.pyc,,
mako/ext/autohandler.py,sha256=QuhNiPSF1LZ53awQ1Qfpwu1Zi9RGOmrtCDnwCLgQzeE,1885
mako/ext/babelplugin.py,sha256=mmt5fG3pcYII1QsrLEV3wH1ltj-C7uKl8vBIpAjxsKY,2091
mako/ext/beaker_cache.py,sha256=4quuJQuXRKKUyF6kM43LQhJT1J2z1KSglRZVDW-7c1I,2578
mako/ext/extract.py,sha256=ZUeaRL2jWcUlrpnhXFXJB0CUJfvQVGBF9tJr5nKJAWI,4659
mako/ext/linguaplugin.py,sha256=sUZalJSI_XeON9aRBb2hds-ilVQaxHKlfCg_nAl7EuU,1935
mako/ext/preprocessors.py,sha256=HYG45idRJUwJkDpswEELL8lPFLisQzgDhW5EHpTDGkI,576
mako/ext/pygmentplugin.py,sha256=TnpJDyQeWTTGHZraMDpw8FB3PNzbmXhaZcjyIBudyi0,4753
mako/ext/turbogears.py,sha256=egv8hradAnnSJwxtmW8uXAsqPUzX8cZZCXclmO_8hMA,2141
mako/filters.py,sha256=IBXyGOby4eFE3UGvNLhJlzbe1FfwJ2dcEr1-gKO_Ljc,4658
mako/lexer.py,sha256=GMq8yf0dEn04-xw2EVDEzaOLXMSVVQz9HyUbfwKnZKg,16321
mako/lookup.py,sha256=4ALORJiL0wIdDvK1okW8rbjq2jL5F_TNASekDFQSULY,12428
mako/parsetree.py,sha256=-wmyX_mklAoKhc-7Psx0U15EKpNSd8oGRXFmvk2JQWo,19021
mako/pygen.py,sha256=689_jR0GG_8Am62Dmlm5h59VY6eyZAU3GroodqEDnZ0,10416
mako/pyparser.py,sha256=3XNxTFQMLJCrRLQdtT5aKLOMU2faRiKfdmadS47vNm8,7478
mako/runtime.py,sha256=ZsUEN22nX3d3dECQujF69mBKDQS6yVv2nvz_0eTvFGg,27804
mako/template.py,sha256=Vn5nLoBY-YzSQJKvRPFGb4fiPyZryA5Q-8mWutv0b9A,23563
mako/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
mako/testing/__pycache__/__init__.cpython-38.pyc,,
mako/testing/__pycache__/_config.cpython-38.pyc,,
mako/testing/__pycache__/assertions.cpython-38.pyc,,
mako/testing/__pycache__/config.cpython-38.pyc,,
mako/testing/__pycache__/exclusions.cpython-38.pyc,,
mako/testing/__pycache__/fixtures.cpython-38.pyc,,
mako/testing/__pycache__/helpers.cpython-38.pyc,,
mako/testing/_config.py,sha256=k-qpnsnbXUoN-ykMN5BRpg84i1x0p6UsAddKQnrIytU,3566
mako/testing/assertions.py,sha256=pfbGl84QlW7QWGg3_lo3wP8XnBAVo9AjzNp2ajmn7FA,5161
mako/testing/config.py,sha256=wmYVZfzGvOK3mJUZpzmgO8-iIgvaCH41Woi4yDpxq6E,323
mako/testing/exclusions.py,sha256=_t6ADKdatk3f18tOfHV_ZY6u_ZwQsKphZ2MXJVSAOcI,1553
mako/testing/fixtures.py,sha256=nEp7wTusf7E0n3Q-BHJW2s_t1vx0KB9poadQ1BmIJzE,3044
mako/testing/helpers.py,sha256=z4HAactwlht4ut1cbvxKt1QLb3yLPk1U7cnh5BwVUlc,1623
mako/util.py,sha256=SNYeX2_PmajQJIR3-S1Yqxxylz8lwS65rC8YbCdTkUU,10638

View File

@ -0,0 +1,5 @@
Wheel-Version: 1.0
Generator: setuptools (75.8.0)
Root-Is-Purelib: true
Tag: py3-none-any

View File

@ -0,0 +1,18 @@
[babel.extractors]
mako = mako.ext.babelplugin:extract [babel]
[console_scripts]
mako-render = mako.cmd:cmdline
[lingua.extractors]
mako = mako.ext.linguaplugin:LinguaMakoExtractor [lingua]
[pygments.lexers]
css+mako = mako.ext.pygmentplugin:MakoCssLexer
html+mako = mako.ext.pygmentplugin:MakoHtmlLexer
js+mako = mako.ext.pygmentplugin:MakoJavascriptLexer
mako = mako.ext.pygmentplugin:MakoLexer
xml+mako = mako.ext.pygmentplugin:MakoXmlLexer
[python.templating.engines]
mako = mako.ext.turbogears:TGPlugin

View File

@ -0,0 +1 @@
mako

View File

@ -0,0 +1 @@
pip

View File

@ -0,0 +1,28 @@
Copyright 2010 Pallets
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,93 @@
Metadata-Version: 2.1
Name: MarkupSafe
Version: 2.1.5
Summary: Safely add untrusted strings to HTML/XML markup.
Home-page: https://palletsprojects.com/p/markupsafe/
Maintainer: Pallets
Maintainer-email: contact@palletsprojects.com
License: BSD-3-Clause
Project-URL: Donate, https://palletsprojects.com/donate
Project-URL: Documentation, https://markupsafe.palletsprojects.com/
Project-URL: Changes, https://markupsafe.palletsprojects.com/changes/
Project-URL: Source Code, https://github.com/pallets/markupsafe/
Project-URL: Issue Tracker, https://github.com/pallets/markupsafe/issues/
Project-URL: Chat, https://discord.gg/pallets
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Text Processing :: Markup :: HTML
Requires-Python: >=3.7
Description-Content-Type: text/x-rst
License-File: LICENSE.rst
MarkupSafe
==========
MarkupSafe implements a text object that escapes characters so it is
safe to use in HTML and XML. Characters that have special meanings are
replaced so that they display as the actual characters. This mitigates
injection attacks, meaning untrusted user input can safely be displayed
on a page.
Installing
----------
Install and update using `pip`_:
.. code-block:: text
pip install -U MarkupSafe
.. _pip: https://pip.pypa.io/en/stable/getting-started/
Examples
--------
.. code-block:: pycon
>>> from markupsafe import Markup, escape
>>> # escape replaces special characters and wraps in Markup
>>> escape("<script>alert(document.cookie);</script>")
Markup('&lt;script&gt;alert(document.cookie);&lt;/script&gt;')
>>> # wrap in Markup to mark text "safe" and prevent escaping
>>> Markup("<strong>Hello</strong>")
Markup('<strong>hello</strong>')
>>> escape(Markup("<strong>Hello</strong>"))
Markup('<strong>hello</strong>')
>>> # Markup is a str subclass
>>> # methods and operators escape their arguments
>>> template = Markup("Hello <em>{name}</em>")
>>> template.format(name='"World"')
Markup('Hello <em>&#34;World&#34;</em>')
Donate
------
The Pallets organization develops and supports MarkupSafe and other
popular packages. In order to grow the community of contributors and
users, and allow the maintainers to devote more time to the projects,
`please donate today`_.
.. _please donate today: https://palletsprojects.com/donate
Links
-----
- Documentation: https://markupsafe.palletsprojects.com/
- Changes: https://markupsafe.palletsprojects.com/changes/
- PyPI Releases: https://pypi.org/project/MarkupSafe/
- Source Code: https://github.com/pallets/markupsafe/
- Issue Tracker: https://github.com/pallets/markupsafe/issues/
- Chat: https://discord.gg/pallets

View File

@ -0,0 +1,14 @@
MarkupSafe-2.1.5.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
MarkupSafe-2.1.5.dist-info/LICENSE.rst,sha256=RjHsDbX9kKVH4zaBcmTGeYIUM4FG-KyUtKV_lu6MnsQ,1503
MarkupSafe-2.1.5.dist-info/METADATA,sha256=icNlaniV7YIQZ1BScCVqNaRtm7MAgfw8d3OBmoSVyAY,3096
MarkupSafe-2.1.5.dist-info/RECORD,,
MarkupSafe-2.1.5.dist-info/WHEEL,sha256=EiQJdJz9MF-Ytxz_yg7pufUbIRgyTkoi17ceXLlE8lo,96
MarkupSafe-2.1.5.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11
markupsafe/__init__.py,sha256=m1ysNeqf55zbEoJtaovca40ivrkEFolPlw5bGoC5Gi4,11290
markupsafe/__pycache__/__init__.cpython-38.pyc,,
markupsafe/__pycache__/_native.cpython-38.pyc,,
markupsafe/_native.py,sha256=_Q7UsXCOvgdonCgqG3l5asANI6eo50EKnDM-mlwEC5M,1776
markupsafe/_speedups.c,sha256=n3jzzaJwXcoN8nTFyA53f3vSqsWK2vujI-v6QYifjhQ,7403
markupsafe/_speedups.cp38-win32.pyd,sha256=0dwrWU7lXVP2qa8QitZ3scCZVZGH7lRlfv4i45ZWdFs,13312
markupsafe/_speedups.pyi,sha256=f5QtwIOP0eLrxh2v5p6SmaYmlcHIGIfmz0DovaqL0OU,238
markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0

View File

@ -0,0 +1,5 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.42.0)
Root-Is-Purelib: false
Tag: cp38-cp38-win32

View File

@ -0,0 +1 @@
markupsafe

View File

@ -0,0 +1 @@
pip

View File

@ -0,0 +1,19 @@
Copyright (c) 2010, 2013 PyMySQL contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,180 @@
Metadata-Version: 2.1
Name: PyMySQL
Version: 1.0.2
Summary: Pure Python MySQL Driver
Home-page: https://github.com/PyMySQL/PyMySQL/
Author: yutaka.matsubara
Author-email: yutaka.matsubara@gmail.com
Maintainer: Inada Naoki
Maintainer-email: songofacandy@gmail.com
License: "MIT"
Project-URL: Documentation, https://pymysql.readthedocs.io/
Keywords: MySQL
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Topic :: Database
Requires-Python: >=3.6
Provides-Extra: ed25519
Requires-Dist: PyNaCl (>=1.4.0) ; extra == 'ed25519'
Provides-Extra: rsa
Requires-Dist: cryptography ; extra == 'rsa'
.. image:: https://readthedocs.org/projects/pymysql/badge/?version=latest
:target: https://pymysql.readthedocs.io/
:alt: Documentation Status
.. image:: https://coveralls.io/repos/PyMySQL/PyMySQL/badge.svg?branch=master&service=github
:target: https://coveralls.io/github/PyMySQL/PyMySQL?branch=master
.. image:: https://img.shields.io/lgtm/grade/python/g/PyMySQL/PyMySQL.svg?logo=lgtm&logoWidth=18
:target: https://lgtm.com/projects/g/PyMySQL/PyMySQL/context:python
PyMySQL
=======
.. contents:: Table of Contents
:local:
This package contains a pure-Python MySQL client library, based on `PEP 249`_.
Most public APIs are compatible with mysqlclient and MySQLdb.
NOTE: PyMySQL doesn't support low level APIs `_mysql` provides like `data_seek`,
`store_result`, and `use_result`. You should use high level APIs defined in `PEP 249`_.
But some APIs like `autocommit` and `ping` are supported because `PEP 249`_ doesn't cover
their usecase.
.. _`PEP 249`: https://www.python.org/dev/peps/pep-0249/
Requirements
-------------
* Python -- one of the following:
- CPython_ : 3.6 and newer
- PyPy_ : Latest 3.x version
* MySQL Server -- one of the following:
- MySQL_ >= 5.6
- MariaDB_ >= 10.0
.. _CPython: https://www.python.org/
.. _PyPy: https://pypy.org/
.. _MySQL: https://www.mysql.com/
.. _MariaDB: https://mariadb.org/
Installation
------------
Package is uploaded on `PyPI <https://pypi.org/project/PyMySQL>`_.
You can install it with pip::
$ python3 -m pip install PyMySQL
To use "sha256_password" or "caching_sha2_password" for authenticate,
you need to install additional dependency::
$ python3 -m pip install PyMySQL[rsa]
To use MariaDB's "ed25519" authentication method, you need to install
additional dependency::
$ python3 -m pip install PyMySQL[ed25519]
Documentation
-------------
Documentation is available online: https://pymysql.readthedocs.io/
For support, please refer to the `StackOverflow
<https://stackoverflow.com/questions/tagged/pymysql>`_.
Example
-------
The following examples make use of a simple table
.. code:: sql
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(255) COLLATE utf8_bin NOT NULL,
`password` varchar(255) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
AUTO_INCREMENT=1 ;
.. code:: python
import pymysql.cursors
# Connect to the database
connection = pymysql.connect(host='localhost',
user='user',
password='passwd',
database='db',
cursorclass=pymysql.cursors.DictCursor)
with connection:
with connection.cursor() as cursor:
# Create a new record
sql = "INSERT INTO `users` (`email`, `password`) VALUES (%s, %s)"
cursor.execute(sql, ('webmaster@python.org', 'very-secret'))
# connection is not autocommit by default. So you must commit to save
# your changes.
connection.commit()
with connection.cursor() as cursor:
# Read a single record
sql = "SELECT `id`, `password` FROM `users` WHERE `email`=%s"
cursor.execute(sql, ('webmaster@python.org',))
result = cursor.fetchone()
print(result)
This example will print:
.. code:: python
{'password': 'very-secret', 'id': 1}
Resources
---------
* DB-API 2.0: https://www.python.org/dev/peps/pep-0249/
* MySQL Reference Manuals: https://dev.mysql.com/doc/
* MySQL client/server protocol:
https://dev.mysql.com/doc/internals/en/client-server-protocol.html
* "Connector" channel in MySQL Community Slack:
https://lefred.be/mysql-community-on-slack/
* PyMySQL mailing list: https://groups.google.com/forum/#!forum/pymysql-users
License
-------
PyMySQL is released under the MIT License. See LICENSE for more information.

View File

@ -0,0 +1,43 @@
PyMySQL-1.0.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
PyMySQL-1.0.2.dist-info/LICENSE,sha256=MUEg3GXwgA9ziksxQAx27hTezR--d86cNUCkIbhup7Y,1070
PyMySQL-1.0.2.dist-info/METADATA,sha256=hz4Fdo8sOFKcNqZ8wp4Bp-txNCOBCnw9-leYR7QBZ5I,5119
PyMySQL-1.0.2.dist-info/RECORD,,
PyMySQL-1.0.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
PyMySQL-1.0.2.dist-info/WHEEL,sha256=OqRkF0eY5GHssMorFjlbTIq072vpHpF60fIQA6lS9xA,92
PyMySQL-1.0.2.dist-info/top_level.txt,sha256=IKlV-f4o90sOdnMd6HBvo0l2nqfJOGUzkwZeaEEGuRg,8
pymysql/__init__.py,sha256=XL7skPUK4cbKiek68T0vMob-L4YkIRLb2KX4hdMZVvM,4391
pymysql/__pycache__/__init__.cpython-38.pyc,,
pymysql/__pycache__/_auth.cpython-38.pyc,,
pymysql/__pycache__/charset.cpython-38.pyc,,
pymysql/__pycache__/connections.cpython-38.pyc,,
pymysql/__pycache__/converters.cpython-38.pyc,,
pymysql/__pycache__/cursors.cpython-38.pyc,,
pymysql/__pycache__/err.cpython-38.pyc,,
pymysql/__pycache__/optionfile.cpython-38.pyc,,
pymysql/__pycache__/protocol.cpython-38.pyc,,
pymysql/__pycache__/times.cpython-38.pyc,,
pymysql/_auth.py,sha256=l1VtBwDpCtTkalgYQFASO-rj-vEd3DGYR8g-eQjNF1U,7399
pymysql/charset.py,sha256=JCvshFnNf4vzkpXc6uPCyg07qGNfZaVZoxrFqzVlKFs,10293
pymysql/connections.py,sha256=EwKWqFIWlx6kbOeDFIhMFpjJ9-pyF140E5ouKgrrYfY,51251
pymysql/constants/CLIENT.py,sha256=SSvMFPZCTVMU1UWa4zOrfhYMDdR2wG2mS0E5GzJhDsg,878
pymysql/constants/COMMAND.py,sha256=TGITAUcNWlq2Gwg2wv5UK2ykdTd4LYTk_EcJJOCpGIc,679
pymysql/constants/CR.py,sha256=oHyD9dnR1DUX7hd42rcamMnFrWhjUZz7E4S6qQWSQb4,1927
pymysql/constants/ER.py,sha256=cH5wgU-e70wd0uSygNR5IFCnnXcrR9WLwJPMH22bhUw,12296
pymysql/constants/FIELD_TYPE.py,sha256=ytFzgAnGmb9hvdsBlnK68qdZv_a6jYFIXT6VSAb60z8,370
pymysql/constants/FLAG.py,sha256=Fy-PrCLnUI7fx_o5WypYnUAzWAM0E9d5yL8fFRVKffY,214
pymysql/constants/SERVER_STATUS.py,sha256=m28Iq5JGCFCWLhafE73-iOvw_9gDGqnytW3NkHpbugA,333
pymysql/constants/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pymysql/constants/__pycache__/CLIENT.cpython-38.pyc,,
pymysql/constants/__pycache__/COMMAND.cpython-38.pyc,,
pymysql/constants/__pycache__/CR.cpython-38.pyc,,
pymysql/constants/__pycache__/ER.cpython-38.pyc,,
pymysql/constants/__pycache__/FIELD_TYPE.cpython-38.pyc,,
pymysql/constants/__pycache__/FLAG.cpython-38.pyc,,
pymysql/constants/__pycache__/SERVER_STATUS.cpython-38.pyc,,
pymysql/constants/__pycache__/__init__.cpython-38.pyc,,
pymysql/converters.py,sha256=MBXTOCXSyewMculaRliBEzPVkOKXLiRMqvIXih9Akrg,9430
pymysql/cursors.py,sha256=1E79f3vysxygyfZMhvR6-yFDfysRn3Go8xZTywteh4o,15366
pymysql/err.py,sha256=bpxayM4IUnFQAd8bUZ3PFsFomi9QSfBk-0TJXyKU2FI,3773
pymysql/optionfile.py,sha256=ehPrZW4d7pcEvXGAEpsKgLdXpFnIQD93yF7T_jHjoRk,573
pymysql/protocol.py,sha256=Ur8xXkVvyFc6m5CA34QrHBasADvS_NPFsWU-Q3flRYA,11859
pymysql/times.py,sha256=_qXgDaYwsHntvpIKSKXp1rrYIgtq6Z9pLyLnO2XNoL0,360

View File

@ -0,0 +1,5 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.36.2)
Root-Is-Purelib: true
Tag: py3-none-any

View File

@ -0,0 +1 @@
pymysql

View File

@ -0,0 +1 @@
pip

View File

@ -0,0 +1,19 @@
Copyright 2005-2021 SQLAlchemy authors and contributors <see AUTHORS file>.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,234 @@
Metadata-Version: 2.1
Name: SQLAlchemy
Version: 1.4.22
Summary: Database Abstraction Library
Home-page: https://www.sqlalchemy.org
Author: Mike Bayer
Author-email: mike_mp@zzzcomputing.com
License: MIT
Project-URL: Documentation, https://docs.sqlalchemy.org
Project-URL: Issue Tracker, https://github.com/sqlalchemy/sqlalchemy/
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Database :: Front-Ends
Requires-Python: !=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7
Description-Content-Type: text/x-rst
Requires-Dist: importlib-metadata ; python_version < "3.8"
Requires-Dist: greenlet (!=0.4.17) ; python_version >= "3"
Provides-Extra: aiomysql
Requires-Dist: greenlet (!=0.4.17) ; (python_version >= "3") and extra == 'aiomysql'
Requires-Dist: aiomysql ; (python_version >= "3") and extra == 'aiomysql'
Provides-Extra: aiosqlite
Requires-Dist: greenlet (!=0.4.17) ; (python_version >= "3") and extra == 'aiosqlite'
Requires-Dist: aiosqlite ; (python_version >= "3") and extra == 'aiosqlite'
Provides-Extra: asyncio
Requires-Dist: greenlet (!=0.4.17) ; (python_version >= "3") and extra == 'asyncio'
Provides-Extra: mariadb_connector
Requires-Dist: mariadb (>=1.0.1) ; (python_version >= "3") and extra == 'mariadb_connector'
Provides-Extra: mssql
Requires-Dist: pyodbc ; extra == 'mssql'
Provides-Extra: mssql_pymssql
Requires-Dist: pymssql ; extra == 'mssql_pymssql'
Provides-Extra: mssql_pyodbc
Requires-Dist: pyodbc ; extra == 'mssql_pyodbc'
Provides-Extra: mypy
Requires-Dist: sqlalchemy2-stubs ; extra == 'mypy'
Requires-Dist: mypy (>=0.800) ; (python_version >= "3") and extra == 'mypy'
Provides-Extra: mysql
Requires-Dist: mysqlclient (<2,>=1.4.0) ; (python_version < "3") and extra == 'mysql'
Requires-Dist: mysqlclient (>=1.4.0) ; (python_version >= "3") and extra == 'mysql'
Provides-Extra: mysql_connector
Requires-Dist: mysqlconnector ; extra == 'mysql_connector'
Provides-Extra: oracle
Requires-Dist: cx-oracle (<8,>=7) ; (python_version < "3") and extra == 'oracle'
Requires-Dist: cx-oracle (>=7) ; (python_version >= "3") and extra == 'oracle'
Provides-Extra: postgresql
Requires-Dist: psycopg2 (>=2.7) ; extra == 'postgresql'
Provides-Extra: postgresql_asyncpg
Requires-Dist: greenlet (!=0.4.17) ; (python_version >= "3") and extra == 'postgresql_asyncpg'
Requires-Dist: asyncpg ; (python_version >= "3") and extra == 'postgresql_asyncpg'
Provides-Extra: postgresql_pg8000
Requires-Dist: pg8000 (>=1.16.6) ; extra == 'postgresql_pg8000'
Provides-Extra: postgresql_psycopg2binary
Requires-Dist: psycopg2-binary ; extra == 'postgresql_psycopg2binary'
Provides-Extra: postgresql_psycopg2cffi
Requires-Dist: psycopg2cffi ; extra == 'postgresql_psycopg2cffi'
Provides-Extra: pymysql
Requires-Dist: pymysql (<1) ; (python_version < "3") and extra == 'pymysql'
Requires-Dist: pymysql ; (python_version >= "3") and extra == 'pymysql'
Provides-Extra: sqlcipher
Requires-Dist: sqlcipher3-binary ; (python_version >= "3") and extra == 'sqlcipher'
SQLAlchemy
==========
|PyPI| |Python| |Downloads|
.. |PyPI| image:: https://img.shields.io/pypi/v/sqlalchemy
:target: https://pypi.org/project/sqlalchemy
:alt: PyPI
.. |Python| image:: https://img.shields.io/pypi/pyversions/sqlalchemy
:target: https://pypi.org/project/sqlalchemy
:alt: PyPI - Python Version
.. |Downloads| image:: https://img.shields.io/pypi/dm/sqlalchemy
:target: https://pypi.org/project/sqlalchemy
:alt: PyPI - Downloads
The Python SQL Toolkit and Object Relational Mapper
Introduction
-------------
SQLAlchemy is the Python SQL toolkit and Object Relational Mapper
that gives application developers the full power and
flexibility of SQL. SQLAlchemy provides a full suite
of well known enterprise-level persistence patterns,
designed for efficient and high-performing database
access, adapted into a simple and Pythonic domain
language.
Major SQLAlchemy features include:
* An industrial strength ORM, built
from the core on the identity map, unit of work,
and data mapper patterns. These patterns
allow transparent persistence of objects
using a declarative configuration system.
Domain models
can be constructed and manipulated naturally,
and changes are synchronized with the
current transaction automatically.
* A relationally-oriented query system, exposing
the full range of SQL's capabilities
explicitly, including joins, subqueries,
correlation, and most everything else,
in terms of the object model.
Writing queries with the ORM uses the same
techniques of relational composition you use
when writing SQL. While you can drop into
literal SQL at any time, it's virtually never
needed.
* A comprehensive and flexible system
of eager loading for related collections and objects.
Collections are cached within a session,
and can be loaded on individual access, all
at once using joins, or by query per collection
across the full result set.
* A Core SQL construction system and DBAPI
interaction layer. The SQLAlchemy Core is
separate from the ORM and is a full database
abstraction layer in its own right, and includes
an extensible Python-based SQL expression
language, schema metadata, connection pooling,
type coercion, and custom types.
* All primary and foreign key constraints are
assumed to be composite and natural. Surrogate
integer primary keys are of course still the
norm, but SQLAlchemy never assumes or hardcodes
to this model.
* Database introspection and generation. Database
schemas can be "reflected" in one step into
Python structures representing database metadata;
those same structures can then generate
CREATE statements right back out - all within
the Core, independent of the ORM.
SQLAlchemy's philosophy:
* SQL databases behave less and less like object
collections the more size and performance start to
matter; object collections behave less and less like
tables and rows the more abstraction starts to matter.
SQLAlchemy aims to accommodate both of these
principles.
* An ORM doesn't need to hide the "R". A relational
database provides rich, set-based functionality
that should be fully exposed. SQLAlchemy's
ORM provides an open-ended set of patterns
that allow a developer to construct a custom
mediation layer between a domain model and
a relational schema, turning the so-called
"object relational impedance" issue into
a distant memory.
* The developer, in all cases, makes all decisions
regarding the design, structure, and naming conventions
of both the object model as well as the relational
schema. SQLAlchemy only provides the means
to automate the execution of these decisions.
* With SQLAlchemy, there's no such thing as
"the ORM generated a bad query" - you
retain full control over the structure of
queries, including how joins are organized,
how subqueries and correlation is used, what
columns are requested. Everything SQLAlchemy
does is ultimately the result of a developer-
initiated decision.
* Don't use an ORM if the problem doesn't need one.
SQLAlchemy consists of a Core and separate ORM
component. The Core offers a full SQL expression
language that allows Pythonic construction
of SQL constructs that render directly to SQL
strings for a target database, returning
result sets that are essentially enhanced DBAPI
cursors.
* Transactions should be the norm. With SQLAlchemy's
ORM, nothing goes to permanent storage until
commit() is called. SQLAlchemy encourages applications
to create a consistent means of delineating
the start and end of a series of operations.
* Never render a literal value in a SQL statement.
Bound parameters are used to the greatest degree
possible, allowing query optimizers to cache
query plans effectively and making SQL injection
attacks a non-issue.
Documentation
-------------
Latest documentation is at:
https://www.sqlalchemy.org/docs/
Installation / Requirements
---------------------------
Full documentation for installation is at
`Installation <https://www.sqlalchemy.org/docs/intro.html#installation>`_.
Getting Help / Development / Bug reporting
------------------------------------------
Please refer to the `SQLAlchemy Community Guide <https://www.sqlalchemy.org/support.html>`_.
Code of Conduct
---------------
Above all, SQLAlchemy places great emphasis on polite, thoughtful, and
constructive communication between users and developers.
Please see our current Code of Conduct at
`Code of Conduct <https://www.sqlalchemy.org/codeofconduct.html>`_.
License
-------
SQLAlchemy is distributed under the `MIT license
<https://www.opensource.org/licenses/mit-license.php>`_.

View File

@ -0,0 +1,480 @@
SQLAlchemy-1.4.22.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
SQLAlchemy-1.4.22.dist-info/LICENSE,sha256=YBpAuebmf1_VblyrYHwFdqeATqzBxJ-T6h8-e4s2zW4,1119
SQLAlchemy-1.4.22.dist-info/METADATA,sha256=Od9EA97u5toUkG_2ZDC4gGE7hVMOgFqnl81Lcs0upPs,9392
SQLAlchemy-1.4.22.dist-info/RECORD,,
SQLAlchemy-1.4.22.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
SQLAlchemy-1.4.22.dist-info/WHEEL,sha256=_iQIYqodxlIIeRSKaaUx61MUqAflFno6m3IasYrHq0k,96
SQLAlchemy-1.4.22.dist-info/top_level.txt,sha256=rp-ZgB7D8G11ivXON5VGPjupT1voYmWqkciDt5Uaw_Q,11
sqlalchemy/__init__.py,sha256=7NMOOY5U-e-on03DRNKvjhPvLbguuhwR0HMN2ApgEZA,4242
sqlalchemy/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/__pycache__/events.cpython-38.pyc,,
sqlalchemy/__pycache__/exc.cpython-38.pyc,,
sqlalchemy/__pycache__/inspection.cpython-38.pyc,,
sqlalchemy/__pycache__/log.cpython-38.pyc,,
sqlalchemy/__pycache__/processors.cpython-38.pyc,,
sqlalchemy/__pycache__/schema.cpython-38.pyc,,
sqlalchemy/__pycache__/types.cpython-38.pyc,,
sqlalchemy/cimmutabledict.cp38-win32.pyd,sha256=F2Lgfgzzw3EyFi713IHFHOqT5hzp8jbYx0Su1JA7Wa8,11776
sqlalchemy/connectors/__init__.py,sha256=9R7M0wh_MdUj-WAPV--FHY45VIzVukkrIcAs-AVXiQE,289
sqlalchemy/connectors/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/connectors/__pycache__/mxodbc.cpython-38.pyc,,
sqlalchemy/connectors/__pycache__/pyodbc.cpython-38.pyc,,
sqlalchemy/connectors/mxodbc.py,sha256=xzgqHegww7PtHhRe7bCgVgTkMsqKGegbTh5vDOjE5AU,5950
sqlalchemy/connectors/pyodbc.py,sha256=x9OLqJ1uAZBcpzJE3rVMi_Pv09rOZGQlCQ3Qt_6GfOU,7006
sqlalchemy/cprocessors.cp38-win32.pyd,sha256=lcYmsSZYJmrZ0mWgE5usRvNhzpx7PVm1BZXIlZwuRlY,13312
sqlalchemy/cresultproxy.cp38-win32.pyd,sha256=GVSeA5DUV4ZRNMPolZtyPWVnzWmOE9kDaoBvEtFWas0,17408
sqlalchemy/databases/__init__.py,sha256=mxKoy-gIMRoVgtg8yV4FhkGZlV80H7T_WthG9N1uOKI,1048
sqlalchemy/databases/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/dialects/__init__.py,sha256=8i5fZ2FBQ1UzW0AyKnB2DyJAvBUWD3fAkh12tUVKqcQ,2157
sqlalchemy/dialects/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/dialects/firebird/__init__.py,sha256=qQjx1eAxja3K5XU69G0aY6Lx0iRe3plkHiirfvJII3s,1194
sqlalchemy/dialects/firebird/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/dialects/firebird/__pycache__/base.cpython-38.pyc,,
sqlalchemy/dialects/firebird/__pycache__/fdb.cpython-38.pyc,,
sqlalchemy/dialects/firebird/__pycache__/kinterbasdb.cpython-38.pyc,,
sqlalchemy/dialects/firebird/base.py,sha256=IphYp7SK7caEPFdZl3MIp22h4vmE7knBBPxDdn2CKoY,32160
sqlalchemy/dialects/firebird/fdb.py,sha256=NIEyFOxCwlpX4J7o25N6u-Jn0mR-tnRTz67eB5Gld9A,4228
sqlalchemy/dialects/firebird/kinterbasdb.py,sha256=xiglTtJHqIfCGtKbrh958JZQpuHvX4G303sg3mfgVBU,6681
sqlalchemy/dialects/mssql/__init__.py,sha256=vxGVb_gvKXYpTP00Wf2RQrXXUmqcVJ4J_h7_h2SJ6Qg,1873
sqlalchemy/dialects/mssql/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/dialects/mssql/__pycache__/base.cpython-38.pyc,,
sqlalchemy/dialects/mssql/__pycache__/information_schema.cpython-38.pyc,,
sqlalchemy/dialects/mssql/__pycache__/json.cpython-38.pyc,,
sqlalchemy/dialects/mssql/__pycache__/mxodbc.cpython-38.pyc,,
sqlalchemy/dialects/mssql/__pycache__/provision.cpython-38.pyc,,
sqlalchemy/dialects/mssql/__pycache__/pymssql.cpython-38.pyc,,
sqlalchemy/dialects/mssql/__pycache__/pyodbc.cpython-38.pyc,,
sqlalchemy/dialects/mssql/base.py,sha256=ckfBCiElymQwf2APR9oieoOg_X42bHG23GRQzyU-jFs,110103
sqlalchemy/dialects/mssql/information_schema.py,sha256=JkMcdYPT-OZgVajNzV1V7RbOWHkhXksXufql6hByBbI,7816
sqlalchemy/dialects/mssql/json.py,sha256=bAi9z-htrC6adJUiBRetVj3RwtJ2GNN5I_KGeHFL8_s,4683
sqlalchemy/dialects/mssql/mxodbc.py,sha256=q38_ooZVi2GZ805McU04H-G2umdexSLSt1wpHSBMIHA,4958
sqlalchemy/dialects/mssql/provision.py,sha256=oTGw0l5RNcXIWkA0s2erVgk2XKiNw26IRzZE84tN2uE,4371
sqlalchemy/dialects/mssql/pymssql.py,sha256=vPro0Kq3vstyRi44UIoUTG28mQZjIzN0FmyGisWBhSc,4981
sqlalchemy/dialects/mssql/pyodbc.py,sha256=KhQKGKeC9WfmuWoi5SPB6Te_sxedQMgO96k3k3bYKxE,21198
sqlalchemy/dialects/mysql/__init__.py,sha256=8omvX_h4f6jPZZZqKNSKPJHTS1VNftUVQRmMZ4EkIE8,2262
sqlalchemy/dialects/mysql/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/dialects/mysql/__pycache__/aiomysql.cpython-38.pyc,,
sqlalchemy/dialects/mysql/__pycache__/base.cpython-38.pyc,,
sqlalchemy/dialects/mysql/__pycache__/cymysql.cpython-38.pyc,,
sqlalchemy/dialects/mysql/__pycache__/dml.cpython-38.pyc,,
sqlalchemy/dialects/mysql/__pycache__/enumerated.cpython-38.pyc,,
sqlalchemy/dialects/mysql/__pycache__/expression.cpython-38.pyc,,
sqlalchemy/dialects/mysql/__pycache__/json.cpython-38.pyc,,
sqlalchemy/dialects/mysql/__pycache__/mariadb.cpython-38.pyc,,
sqlalchemy/dialects/mysql/__pycache__/mariadbconnector.cpython-38.pyc,,
sqlalchemy/dialects/mysql/__pycache__/mysqlconnector.cpython-38.pyc,,
sqlalchemy/dialects/mysql/__pycache__/mysqldb.cpython-38.pyc,,
sqlalchemy/dialects/mysql/__pycache__/oursql.cpython-38.pyc,,
sqlalchemy/dialects/mysql/__pycache__/provision.cpython-38.pyc,,
sqlalchemy/dialects/mysql/__pycache__/pymysql.cpython-38.pyc,,
sqlalchemy/dialects/mysql/__pycache__/pyodbc.cpython-38.pyc,,
sqlalchemy/dialects/mysql/__pycache__/reflection.cpython-38.pyc,,
sqlalchemy/dialects/mysql/__pycache__/types.cpython-38.pyc,,
sqlalchemy/dialects/mysql/aiomysql.py,sha256=Wq9UbnxzLCfrTB2dHw-Ofbjx9Bn3u1NgumDNxSEQbAg,9459
sqlalchemy/dialects/mysql/base.py,sha256=3cLKLNyDTR_KVRBf-53F0Zq3KeSYfhnBuwAYgmUjKDQ,121368
sqlalchemy/dialects/mysql/cymysql.py,sha256=bLHR8upJw3fsDJK3YrLMmwp03CYxZBRC0ueS2avreA8,2353
sqlalchemy/dialects/mysql/dml.py,sha256=rRmYkeT-R8ZgfqwSG2uuCPwVMN60AMCJ3IMhVdQNjbw,6355
sqlalchemy/dialects/mysql/enumerated.py,sha256=igWgJtq1g-gWnM12e8xRgalfSPv1LJ3TbNr0S5_kAG0,9397
sqlalchemy/dialects/mysql/expression.py,sha256=rinSVZR7GK6S6OpqNwoUIrbNuT671gObXv5OD_Y6qwk,3867
sqlalchemy/dialects/mysql/json.py,sha256=5XN4UZ7MSbVDpQWiiDeyL64yUEIBy4s5aWtoj580NuY,2397
sqlalchemy/dialects/mysql/mariadb.py,sha256=jE1Hpmka_nKJjWsFHcCVRKWvjg7l1mNCjCzvVADMD-k,523
sqlalchemy/dialects/mysql/mariadbconnector.py,sha256=H6sNtcbz221Q3SafzLHasb9KHLdrutIaRj5JfnDL56k,7756
sqlalchemy/dialects/mysql/mysqlconnector.py,sha256=NYFlULU8QRDkIzuAHMx71QboFaJPRP8nDAsni9ECR24,7930
sqlalchemy/dialects/mysql/mysqldb.py,sha256=kwZlL1xEhU-zd7af8JgxHs3_NlAw6jG40qwi7FD63HA,10855
sqlalchemy/dialects/mysql/oursql.py,sha256=cW---MOJr1JUFDsDUh5tZoUHVfpiZOqWAOgio_JrRmw,8796
sqlalchemy/dialects/mysql/provision.py,sha256=-gCG7MwEMtztSmNU107Q563t-nN-oqTVkCiay-HRRQI,2727
sqlalchemy/dialects/mysql/pymysql.py,sha256=oCiRwX6ui_06q_WdUHYurOBSiTsYa3lLJWO4D13aGr4,2868
sqlalchemy/dialects/mysql/pyodbc.py,sha256=ztvUEUyPx1N5FCH-eInayfk1WWmPE2Zrx0E7mHWjxFg,4635
sqlalchemy/dialects/mysql/reflection.py,sha256=lSVmht9BeGTQZiEswbgrh954Sw6C08xXH0DuiHpIy9U,19111
sqlalchemy/dialects/mysql/types.py,sha256=y8tBh47YE-iIlMy34sQxge62j9jVI_8gmI8AfvUA-9E,25362
sqlalchemy/dialects/oracle/__init__.py,sha256=I0LO6_N2t9cuxB8V8z4D7qCd8STy00Pt3YN9mMyxpFk,1287
sqlalchemy/dialects/oracle/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/dialects/oracle/__pycache__/base.cpython-38.pyc,,
sqlalchemy/dialects/oracle/__pycache__/cx_oracle.cpython-38.pyc,,
sqlalchemy/dialects/oracle/__pycache__/provision.cpython-38.pyc,,
sqlalchemy/dialects/oracle/base.py,sha256=ra3dvQ3ziEOihRRmn14P5QmXYOmKjkzYBOCL0XAFhqI,89014
sqlalchemy/dialects/oracle/cx_oracle.py,sha256=o4NrPXFkIgUsr2I4B_gKWqxIBUoIAg_U9L3svNHs0sY,50473
sqlalchemy/dialects/oracle/provision.py,sha256=HCi5hs5fv6rXv-lVQir6gsKrhes9NoAWlChzR3ueq74,5965
sqlalchemy/dialects/postgresql/__init__.py,sha256=qPxMM9lQd7YmgmUefA3j4oIcRfZZl3qwa1PGZ27vPgI,2626
sqlalchemy/dialects/postgresql/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/dialects/postgresql/__pycache__/array.cpython-38.pyc,,
sqlalchemy/dialects/postgresql/__pycache__/asyncpg.cpython-38.pyc,,
sqlalchemy/dialects/postgresql/__pycache__/base.cpython-38.pyc,,
sqlalchemy/dialects/postgresql/__pycache__/dml.cpython-38.pyc,,
sqlalchemy/dialects/postgresql/__pycache__/ext.cpython-38.pyc,,
sqlalchemy/dialects/postgresql/__pycache__/hstore.cpython-38.pyc,,
sqlalchemy/dialects/postgresql/__pycache__/json.cpython-38.pyc,,
sqlalchemy/dialects/postgresql/__pycache__/pg8000.cpython-38.pyc,,
sqlalchemy/dialects/postgresql/__pycache__/provision.cpython-38.pyc,,
sqlalchemy/dialects/postgresql/__pycache__/psycopg2.cpython-38.pyc,,
sqlalchemy/dialects/postgresql/__pycache__/psycopg2cffi.cpython-38.pyc,,
sqlalchemy/dialects/postgresql/__pycache__/pygresql.cpython-38.pyc,,
sqlalchemy/dialects/postgresql/__pycache__/pypostgresql.cpython-38.pyc,,
sqlalchemy/dialects/postgresql/__pycache__/ranges.cpython-38.pyc,,
sqlalchemy/dialects/postgresql/array.py,sha256=HT-09_-hliM77Vjqs9yh6EdeZBmi5CeGPV2fkKRXdbE,12616
sqlalchemy/dialects/postgresql/asyncpg.py,sha256=bKKU_egRS74hGm93s5x_EzuKgS0egj8v-NQVwQjasyQ,34475
sqlalchemy/dialects/postgresql/base.py,sha256=iYD_1DmViRkz2YlzF2dAFyppMzOeW8tTFeU1dQ1Qtc0,156527
sqlalchemy/dialects/postgresql/dml.py,sha256=4ReHHNxI72rDD61VXvDCoGaDqh6EqcuLlGEsAQWuSCw,9829
sqlalchemy/dialects/postgresql/ext.py,sha256=3gEVNqMPtW0cY44RzNqbre9pbWFIkcjjqVf1afreUP0,8658
sqlalchemy/dialects/postgresql/hstore.py,sha256=C7G3JKnPZFfS7Y8je-81xSPDOdFleDJrehY4FxCgAEA,12838
sqlalchemy/dialects/postgresql/json.py,sha256=6GqHHVHPBPMMdMdtIxnIZDa3ftyEil5LI6lDGC3Qp5c,10778
sqlalchemy/dialects/postgresql/pg8000.py,sha256=GgtCCswsvqzPccxNjljACdJlqoJXbkZ3tjq7cOKLxVA,17391
sqlalchemy/dialects/postgresql/provision.py,sha256=EgdZRObrTzwZ7jaBA_oPkWx3Ly1Cathw4pOfWZm6Pn0,4543
sqlalchemy/dialects/postgresql/psycopg2.py,sha256=jImZnPD5vc-fyoRMjWgGFMweKSWSGx2-eMCLGQ6EQjo,39901
sqlalchemy/dialects/postgresql/psycopg2cffi.py,sha256=l0BcgY5wsG4uhmUtP9Ksn2fdxBe7T3y0j0PeYSksDpc,1751
sqlalchemy/dialects/postgresql/pygresql.py,sha256=5U4yGfmL5yhiu3I4OxJ0lXzFn1kcZf8Rlj1B8RTdSC0,8863
sqlalchemy/dialects/postgresql/pypostgresql.py,sha256=EZfy4yTFgWtXUkHbYe_48JnHM_VB6WScbwqcC5e39GQ,3819
sqlalchemy/dialects/postgresql/ranges.py,sha256=7zwQ_x8AJbe8s4heeUW7DvsCa0M_SQYkBsHX37RJkHU,4764
sqlalchemy/dialects/sqlite/__init__.py,sha256=eXKVjUjgbWCVsTrl4vLZInTJc3Pn_dC4EQAIaqb5WuU,1256
sqlalchemy/dialects/sqlite/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/dialects/sqlite/__pycache__/aiosqlite.cpython-38.pyc,,
sqlalchemy/dialects/sqlite/__pycache__/base.cpython-38.pyc,,
sqlalchemy/dialects/sqlite/__pycache__/dml.cpython-38.pyc,,
sqlalchemy/dialects/sqlite/__pycache__/json.cpython-38.pyc,,
sqlalchemy/dialects/sqlite/__pycache__/provision.cpython-38.pyc,,
sqlalchemy/dialects/sqlite/__pycache__/pysqlcipher.cpython-38.pyc,,
sqlalchemy/dialects/sqlite/__pycache__/pysqlite.cpython-38.pyc,,
sqlalchemy/dialects/sqlite/aiosqlite.py,sha256=Dp6s8ZzG75rjS4_2uGsV-YI1Iunewb6GP2FeMRHncXM,10180
sqlalchemy/dialects/sqlite/base.py,sha256=lewKdUuoFh2RbumZbA_NfRnOeeNg-bEvpcCk8G2dhDI,90666
sqlalchemy/dialects/sqlite/dml.py,sha256=1MZ70pY0fgVWs_8-KZLWlvtzR4ZdTO4r_vqfBuMj42M,7038
sqlalchemy/dialects/sqlite/json.py,sha256=bz_1axFG5YI9kLszE-oiCN3-z95zIPPcLgVwug_-AT4,2602
sqlalchemy/dialects/sqlite/provision.py,sha256=3F5ZX2dYGMFAGra99UVavCihth1_XazJXX9XAet8gbw,4818
sqlalchemy/dialects/sqlite/pysqlcipher.py,sha256=OhM80N9ZrcVXQhPvbQ0l70ZZkH8ItyiYLkIP4yesE50,5769
sqlalchemy/dialects/sqlite/pysqlite.py,sha256=IMpoIMCHrJvvBCl1No00N5MNtcNTt3Rw3Zzx6wmn-S4,23902
sqlalchemy/dialects/sybase/__init__.py,sha256=iu3g_UdZebWi3vEb_dvl-o9LcHxLPSQxUDd11ZF6Lrc,1431
sqlalchemy/dialects/sybase/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/dialects/sybase/__pycache__/base.cpython-38.pyc,,
sqlalchemy/dialects/sybase/__pycache__/mxodbc.cpython-38.pyc,,
sqlalchemy/dialects/sybase/__pycache__/pyodbc.cpython-38.pyc,,
sqlalchemy/dialects/sybase/__pycache__/pysybase.cpython-38.pyc,,
sqlalchemy/dialects/sybase/base.py,sha256=XaFBcW1BzX0W0R26MpdUfBEgdcTbcsKhsDDTwNYuMG0,33521
sqlalchemy/dialects/sybase/mxodbc.py,sha256=1MJQ95Rt6tI7h8ihCN8q_TGuzhSgLocSCmGqumU1dbI,973
sqlalchemy/dialects/sybase/pyodbc.py,sha256=Q5zyi3KBIiiJaxouthkDeeK0k725PqXkc2WA1UsgI4M,2319
sqlalchemy/dialects/sybase/pysybase.py,sha256=doOLJtsapSIzXGxql7KRk4DdzpTXcwIvuk6BUeSZHzM,3476
sqlalchemy/engine/__init__.py,sha256=ciy5T0J4arFIffczHNMb5aJ00GyXgfotBzkTLW8EuXc,2093
sqlalchemy/engine/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/engine/__pycache__/base.cpython-38.pyc,,
sqlalchemy/engine/__pycache__/characteristics.cpython-38.pyc,,
sqlalchemy/engine/__pycache__/create.cpython-38.pyc,,
sqlalchemy/engine/__pycache__/cursor.cpython-38.pyc,,
sqlalchemy/engine/__pycache__/default.cpython-38.pyc,,
sqlalchemy/engine/__pycache__/events.cpython-38.pyc,,
sqlalchemy/engine/__pycache__/interfaces.cpython-38.pyc,,
sqlalchemy/engine/__pycache__/mock.cpython-38.pyc,,
sqlalchemy/engine/__pycache__/reflection.cpython-38.pyc,,
sqlalchemy/engine/__pycache__/result.cpython-38.pyc,,
sqlalchemy/engine/__pycache__/row.cpython-38.pyc,,
sqlalchemy/engine/__pycache__/strategies.cpython-38.pyc,,
sqlalchemy/engine/__pycache__/url.cpython-38.pyc,,
sqlalchemy/engine/__pycache__/util.cpython-38.pyc,,
sqlalchemy/engine/base.py,sha256=Lbt_A0Xk-K8mhpyA00hlpK7plTAb-_hOi1kNGLKRf5s,121315
sqlalchemy/engine/characteristics.py,sha256=DrhLcmpnkMpmgo_kgQpcujoD4nW81vTt-GkuWqW9QaY,1873
sqlalchemy/engine/create.py,sha256=DOflKNxncPJYk2TNiJwFLtjYtZqXzW7tiFFRQpDnftg,31145
sqlalchemy/engine/cursor.py,sha256=knJP41oy3UOwJ1E5lEYrZ9wpSd8q9TDsAVFpy5kaHqo,69826
sqlalchemy/engine/default.py,sha256=B0LAJlEkPZzs4xitGWszSgpoiBqdDGxtvOY83lKUpYw,66315
sqlalchemy/engine/events.py,sha256=oFyWy9AIj8HUqVSRGB4BvS0rDWc-3j2NBHv6_Ckl59c,33484
sqlalchemy/engine/interfaces.py,sha256=008-DIAPPXbgCeeu2_mg34E67UbtQGcl1V39egozulY,60761
sqlalchemy/engine/mock.py,sha256=w4zCNsRxe9d4RoiprXOPgekAsBcZhFUFFuahgSpbu7I,3744
sqlalchemy/engine/reflection.py,sha256=7crAG7fG9sfs6CcCNBLe9d1ki8Wx9rOIAhnte0RiwBg,39756
sqlalchemy/engine/result.py,sha256=ejfiTOQyX03nHIKhoZCk2csMELKHpE0J6bEQOgJ5Mbg,55462
sqlalchemy/engine/row.py,sha256=cFjoUn1QYfgMqs2VkjRzNlTysF0ptE6k_RMBsqpSuGE,18800
sqlalchemy/engine/strategies.py,sha256=t1Q0jIlyxe6z9ph4TOFaViLjMYODQk6akTKAc8smxVI,431
sqlalchemy/engine/url.py,sha256=haqrKM672oXhR8qysrvzmvA2VIP6Mdp6yYv8CXGEAHM,26201
sqlalchemy/engine/util.py,sha256=TIS9VU_mcFHgz3N8rAB2z4JUwQh8asXCIMkBWBOyeKE,7876
sqlalchemy/event/__init__.py,sha256=XreIYU5ZboKOqh0OhNwlD_BM6Q_CpFnB_RwBqB_3uPw,534
sqlalchemy/event/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/event/__pycache__/api.cpython-38.pyc,,
sqlalchemy/event/__pycache__/attr.cpython-38.pyc,,
sqlalchemy/event/__pycache__/base.cpython-38.pyc,,
sqlalchemy/event/__pycache__/legacy.cpython-38.pyc,,
sqlalchemy/event/__pycache__/registry.cpython-38.pyc,,
sqlalchemy/event/api.py,sha256=d0cvMJR-3_w01dW6FzDyKmpaf6K2S8fGHidn2SsbazY,6995
sqlalchemy/event/attr.py,sha256=z2gqp7Cpa1Q18Ng4dyzZRceDtbamMVGt0KiJ-S43F-k,15093
sqlalchemy/event/base.py,sha256=IwlUCiQUM3RMtBnf7iqHw7wkTXYVabWdm9yyfV2IPzs,11281
sqlalchemy/event/legacy.py,sha256=nF-QWFPHPpUQVPYR0nVGpOZ-0PSpvDLew4IK0jB9gZY,6455
sqlalchemy/event/registry.py,sha256=U4_rjtE36ZAGXiH6D9seLNzfNdewRLy3f2B7HOPP1J8,8783
sqlalchemy/events.py,sha256=miQEoutDD_jq5JPe71LV7a02CEGYZOryS6t12qLjSMk,481
sqlalchemy/exc.py,sha256=C4X6NsAe_sz8KooZ4aIoroGB-oBv1Hq-H44-n2ZNoJ4,20962
sqlalchemy/ext/__init__.py,sha256=_IOFj7IDQZZT8ysB2lpotQgBTo53EkqUnRe_vfTLuVU,333
sqlalchemy/ext/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/ext/__pycache__/associationproxy.cpython-38.pyc,,
sqlalchemy/ext/__pycache__/automap.cpython-38.pyc,,
sqlalchemy/ext/__pycache__/baked.cpython-38.pyc,,
sqlalchemy/ext/__pycache__/compiler.cpython-38.pyc,,
sqlalchemy/ext/__pycache__/horizontal_shard.cpython-38.pyc,,
sqlalchemy/ext/__pycache__/hybrid.cpython-38.pyc,,
sqlalchemy/ext/__pycache__/indexable.cpython-38.pyc,,
sqlalchemy/ext/__pycache__/instrumentation.cpython-38.pyc,,
sqlalchemy/ext/__pycache__/mutable.cpython-38.pyc,,
sqlalchemy/ext/__pycache__/orderinglist.cpython-38.pyc,,
sqlalchemy/ext/__pycache__/serializer.cpython-38.pyc,,
sqlalchemy/ext/associationproxy.py,sha256=Dba12TOxOTKkWciyuDmF34vpJ9jd9VXFzksRZt6a3xc,51570
sqlalchemy/ext/asyncio/__init__.py,sha256=S4AkBA8do84Z00lagJIU1DIvErCsppEBI5quT7_PEFI,799
sqlalchemy/ext/asyncio/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/ext/asyncio/__pycache__/base.cpython-38.pyc,,
sqlalchemy/ext/asyncio/__pycache__/engine.cpython-38.pyc,,
sqlalchemy/ext/asyncio/__pycache__/events.cpython-38.pyc,,
sqlalchemy/ext/asyncio/__pycache__/exc.cpython-38.pyc,,
sqlalchemy/ext/asyncio/__pycache__/result.cpython-38.pyc,,
sqlalchemy/ext/asyncio/__pycache__/scoping.cpython-38.pyc,,
sqlalchemy/ext/asyncio/__pycache__/session.cpython-38.pyc,,
sqlalchemy/ext/asyncio/base.py,sha256=DQjKnvQPq6d_WwCbks3NSRVt9mcU2u8xojaV3E60Zno,2291
sqlalchemy/ext/asyncio/engine.py,sha256=Elf8GmKzYS6DaZLd3Vs341S_hw4ErOVNwj4-XJ2HVmE,23752
sqlalchemy/ext/asyncio/events.py,sha256=E_1w1IR_-I8WlCKK5OFUgNpzXCWvYPVWvcwsnkR_3uw,1271
sqlalchemy/ext/asyncio/exc.py,sha256=JuPU1z3THX9eshfFtUMkE-Yk-jt1xXtKrbG5V_BeXqg,660
sqlalchemy/ext/asyncio/result.py,sha256=0Yw_05OkfpluaSYvjwxJPY-NXs3BcrYSw2yAI6Oetek,21086
sqlalchemy/ext/asyncio/scoping.py,sha256=T78SRIG6dO2_HEIw56oy13jkbEeG0iscxr1gLD7YGec,2948
sqlalchemy/ext/asyncio/session.py,sha256=8PMhokUPBimxCk7cSg7BkKR_14rdZ8OJBK9EkTqoDP0,15393
sqlalchemy/ext/automap.py,sha256=nZyOR8I4FaDiQGiKiccSAZm7D_nOZZarEYiMIEfxDRg,46419
sqlalchemy/ext/baked.py,sha256=c4MZL4ZiC_JOr_FhRqVJQGm9n_kVGh_7vRtIynBbfYw,20617
sqlalchemy/ext/compiler.py,sha256=7bWnrFeV_-56BYLNrEaKNkI5EKaiz9epc0TDUwa6Y_c,18497
sqlalchemy/ext/declarative/__init__.py,sha256=djj3b6PIoMQj7P-W6GWwwb2BGL764-Yx9qEnDiGiaz4,1906
sqlalchemy/ext/declarative/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/ext/declarative/__pycache__/extensions.cpython-38.pyc,,
sqlalchemy/ext/declarative/extensions.py,sha256=6CTE_iJ7pJe3KXuFk-IctUdqm1CLa9KvezVjNC44Ixw,16867
sqlalchemy/ext/horizontal_shard.py,sha256=fTybSwNWM8fjPoBPh0wcm4p7ng7jco62v7KTVZqb8VQ,8991
sqlalchemy/ext/hybrid.py,sha256=176v17TzDt-RthN-_bw57UuItXRLAV-g8h6Enc6I35Q,43105
sqlalchemy/ext/indexable.py,sha256=Yqgp8J_dEUYsWUabGTOvyXasqY7qr_84ruSV0mqXKBU,11607
sqlalchemy/ext/instrumentation.py,sha256=kx2zn8mN30F-CbWqiBxb7HgnMSJChLcvQhJ8Tb8VIXo,14802
sqlalchemy/ext/mutable.py,sha256=AmkDIhuTF0z0FhrMTq97nDPYlDtPwdkpXwVKBh03MT8,32948
sqlalchemy/ext/mypy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
sqlalchemy/ext/mypy/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/ext/mypy/__pycache__/apply.cpython-38.pyc,,
sqlalchemy/ext/mypy/__pycache__/decl_class.cpython-38.pyc,,
sqlalchemy/ext/mypy/__pycache__/infer.cpython-38.pyc,,
sqlalchemy/ext/mypy/__pycache__/names.cpython-38.pyc,,
sqlalchemy/ext/mypy/__pycache__/plugin.cpython-38.pyc,,
sqlalchemy/ext/mypy/__pycache__/util.cpython-38.pyc,,
sqlalchemy/ext/mypy/apply.py,sha256=_2Ug51mWUADhnk5U_WWoClS5ZwTreZL6Hbvz9OHR0hI,9297
sqlalchemy/ext/mypy/decl_class.py,sha256=pfLl9ZF_ysV99XqsTvQdz--lJIT_ZDCbyTJKnfGnFhw,17041
sqlalchemy/ext/mypy/infer.py,sha256=43snbm7rGWqgFmsStDNkF5W-SWSm5_vJgIBXL1pzmNc,17691
sqlalchemy/ext/mypy/names.py,sha256=kxFoVvTvPDeOBVbc8GpWh8cST_Lv-rLrEsEVQ6OvkHI,7903
sqlalchemy/ext/mypy/plugin.py,sha256=pJmF0c5FuuDeOMEcuNE4l1fYdTTmZ_Eyq7e8g59AQz4,9956
sqlalchemy/ext/mypy/util.py,sha256=U5IzfJart5sqq2eM9zhFQQHxoA4w9XJXQmWSImVX_ak,6236
sqlalchemy/ext/orderinglist.py,sha256=r-NMePBtFl37NXG_W08cYz7kQ3rTpWV51KYZ4PUJ7VY,14263
sqlalchemy/ext/serializer.py,sha256=9fZbqOVD2Tw3umIhnf5mU_9P0We9aBogxv-HJxZ0d2o,6133
sqlalchemy/future/__init__.py,sha256=1agu_FUR_f5j3XLUwfh1WoBWghZX2PpcvO0bvaZiSis,543
sqlalchemy/future/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/future/__pycache__/engine.cpython-38.pyc,,
sqlalchemy/future/engine.py,sha256=2Qc97YYmaKSp0jyOF4X6S6efF4btcsuj3c0Wpu1PlNU,16993
sqlalchemy/future/orm/__init__.py,sha256=PkzdGJzfKaxXrGL3_nCkSlVhxnVa3IPbOr96Yf1EbXg,299
sqlalchemy/future/orm/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/inspection.py,sha256=GOUbF3OA24hZeGxzOZBeTjb23QuGtMPwPp_e0x9xGJI,3144
sqlalchemy/log.py,sha256=ZYPQpq9Jh7Ab8TpWNWj7PPwt-D3h-3wxqwuosxzhfXU,6995
sqlalchemy/orm/__init__.py,sha256=pyEekXUthKxP3N2aBiIG7u6tyIPsK6sN9N9tSZNSOZE,10770
sqlalchemy/orm/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/attributes.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/base.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/clsregistry.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/collections.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/context.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/decl_api.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/decl_base.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/dependency.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/descriptor_props.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/dynamic.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/evaluator.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/events.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/exc.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/identity.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/instrumentation.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/interfaces.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/loading.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/mapper.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/path_registry.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/persistence.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/properties.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/query.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/relationships.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/scoping.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/session.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/state.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/strategies.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/strategy_options.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/sync.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/unitofwork.cpython-38.pyc,,
sqlalchemy/orm/__pycache__/util.cpython-38.pyc,,
sqlalchemy/orm/attributes.py,sha256=MfF4S6oz7zdfjQtq8zEBeeUydyfn4u2va1AoNg9MSGI,78905
sqlalchemy/orm/base.py,sha256=VAfg8c7tr77wW6YNH4jGje9ZyDYOdiiOEQjfWmh9MjY,15640
sqlalchemy/orm/clsregistry.py,sha256=ze1nonwKAW0KUwNihFlrAJv517Sd4FRdlXw454JugJo,13732
sqlalchemy/orm/collections.py,sha256=_NmtExwLSgfgFczNUl1Jz0WPHJabRoL4P0FX08q5rv0,56417
sqlalchemy/orm/context.py,sha256=NG72jbDa_sAH7r5Ijy5rQUGZMinKTEz5YT7QWp30gC4,106826
sqlalchemy/orm/decl_api.py,sha256=ECncblg5juwXrrGzc-ruKks1lpjH5J6ut36yOrNEWwg,35962
sqlalchemy/orm/decl_base.py,sha256=D3Qw5p7QRzCo4-Q1nnHeeaHPJg17kR5Ohpz-g7VSwnU,43850
sqlalchemy/orm/dependency.py,sha256=VTdKsj-gh-8l0e97oiAZsPvd0iKF8MTANk2uJtksLU8,48269
sqlalchemy/orm/descriptor_props.py,sha256=Lpe6BZUV7rBB1Yzbq8X0-Em8bo-r9msJ7UFdncpP3Nc,26702
sqlalchemy/orm/dynamic.py,sha256=AIKXgSmGXQ5fFv9HkoNj2_ChgbzdjmwZ3gSSEnar3LA,16307
sqlalchemy/orm/evaluator.py,sha256=v_4PH0oOyiESW-8xVCQ5-jwmvVksf3kh7qCMExMcHzM,7093
sqlalchemy/orm/events.py,sha256=52oYUhI3K8r-m0Qw-3W1H4br0s58AZegEZ7GQ6nmdok,113099
sqlalchemy/orm/exc.py,sha256=HEIHiFBDPCdU-Vp5nUY0jnvUlIBXsgAGZOmNjB6HaJU,6736
sqlalchemy/orm/identity.py,sha256=DL3YxgDMr_NJaEsOIIOnJ_JrpX5TTolYNUYWu0KdEfs,7041
sqlalchemy/orm/instrumentation.py,sha256=Ck-84bGBBFpOmUghjdDZDoSgKXPPDUUQ9H2yBz0h1Ac,20999
sqlalchemy/orm/interfaces.py,sha256=r9L8RjvlY0O9KOQMK6jHL6gVMzX15IQIsVsh7T8ycec,29348
sqlalchemy/orm/loading.py,sha256=uEqu6kQ1WltLQBQ0jLlxLUknK2YFxDHDVwqPN1Ieo4I,51858
sqlalchemy/orm/mapper.py,sha256=u1a0BJVcIA3HVVuWE4yb0VUDCoU89TwcLeE6TmbmWLU,139809
sqlalchemy/orm/path_registry.py,sha256=kSnwlOAzyriHKWXsZdjsxzVBHEpBEoat-0h3CmGrgoE,15589
sqlalchemy/orm/persistence.py,sha256=o22uaX6lAXWwYculFEV9S83Tp9hX1wBl39P7067GGqk,81402
sqlalchemy/orm/properties.py,sha256=RIcVZqQaOqx5hIFrnFqFCxo7ZK32758UxG-339PbsQM,15320
sqlalchemy/orm/query.py,sha256=XSWifY9G5cjMmzvHQl2c6n26I1cre5giNugfqzosc4o,125306
sqlalchemy/orm/relationships.py,sha256=Q-Ejp9N5AmGg9F-ZmOobWcbwqmm-B5JNEgoY3j0MKqs,146605
sqlalchemy/orm/scoping.py,sha256=o3l2Fwxu6OkqHL63Go_EXMZScF5EmSyqJq3n2Nq2p2s,6881
sqlalchemy/orm/session.py,sha256=MiZa4zrLLlaYqOHfWI-j3ADqnWV0AR5r0ut1OVsU8M8,159852
sqlalchemy/orm/state.py,sha256=GtdGI_Kk8zvUMKmRYBbdiX6GbAS1jjasP9sH31D9IEI,34432
sqlalchemy/orm/strategies.py,sha256=Vgyd3yy3PMsRJXkiS-t7OeKwD_uEzvoQH2EV4qE8Pxo,110338
sqlalchemy/orm/strategy_options.py,sha256=XklpEn88jYMfEefEM8EyGij3KdQdImfWsc3E5vWPdDY,63566
sqlalchemy/orm/sync.py,sha256=i4_pckRzwuteE7Eoq2_tZ3YJHYLp34Ip5UvvjR9xUVw,5991
sqlalchemy/orm/unitofwork.py,sha256=ih7G9uAet5DxkAA5-yXB3hJZqVjklie469uTX4mSvSI,27874
sqlalchemy/orm/util.py,sha256=VtLTunDA3PnllCXh8p8QlxHTUfbfa4zlJ2se8wTx5gw,70602
sqlalchemy/pool/__init__.py,sha256=pxU58-DDcAI-iJnlNdTLMXKKarUIMO0IurslcpZtGjw,1659
sqlalchemy/pool/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/pool/__pycache__/base.cpython-38.pyc,,
sqlalchemy/pool/__pycache__/dbapi_proxy.cpython-38.pyc,,
sqlalchemy/pool/__pycache__/events.cpython-38.pyc,,
sqlalchemy/pool/__pycache__/impl.cpython-38.pyc,,
sqlalchemy/pool/base.py,sha256=4JYRdKzWoFsoinKUwbw3rYPqrPOVZrKO_ks8g2OqhK8,36658
sqlalchemy/pool/dbapi_proxy.py,sha256=t5tN6PjqbNPi8qJNbdKK-1aWIVZ1ieV0vmxXsoHAzp8,4376
sqlalchemy/pool/events.py,sha256=raAkg0pErdheJxrHr56B48m4yJqfp20_HFoHJtn_Qkw,8943
sqlalchemy/pool/impl.py,sha256=fUPdAqW8i-t--CqGslQyQmIiS-RzhoLTz_tyCC35EnE,16285
sqlalchemy/processors.py,sha256=seo5tJyEcZI7nhjt_4TNovfLUMMjl2kerStSXOZwy8k,5921
sqlalchemy/schema.py,sha256=hE9BHCyIyG7bD3iOEQJ1r9el-_dVsrRf4Ga3m7KGE9U,2472
sqlalchemy/sql/__init__.py,sha256=LbTzY2myefIGr3fI8VfSxve-7Q8taYSCj9VP-Hu2rsA,4811
sqlalchemy/sql/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/annotation.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/base.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/coercions.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/compiler.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/crud.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/ddl.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/default_comparator.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/dml.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/elements.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/events.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/expression.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/functions.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/lambdas.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/naming.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/operators.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/roles.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/schema.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/selectable.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/sqltypes.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/traversals.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/type_api.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/util.cpython-38.pyc,,
sqlalchemy/sql/__pycache__/visitors.cpython-38.pyc,,
sqlalchemy/sql/annotation.py,sha256=jjX7XMd1X6hq_NJHpq97dymriDSca2W2-zEM1vmBDOo,11593
sqlalchemy/sql/base.py,sha256=i1VZIC2AV-f-xQBqUKOFGt4bM3OQ8gapCOPYwQgjBEg,56652
sqlalchemy/sql/coercions.py,sha256=Ix7Wt2Y2bucFu2QY5GIiNoqyoZHlwVVVAx0FmjiwDPQ,34044
sqlalchemy/sql/compiler.py,sha256=culOTMGiHYyYkOmuFqDTwG8JivxC9HbXlIVmuNskG8w,183335
sqlalchemy/sql/crud.py,sha256=dIUIj4-VbhyfzNQkoOE_nGYXQzmLk_rKXF5rGoin2bk,36170
sqlalchemy/sql/ddl.py,sha256=DjIfWmNLDTh2K_89cLFpv5FG11tUjbTmDlQhye1SwpY,45338
sqlalchemy/sql/default_comparator.py,sha256=xbt0dNEcQ7-Ud89uGlz1lFocpBy2Yoq35IRr1Ftv7GA,11234
sqlalchemy/sql/dml.py,sha256=qYXLbtMdipd1PpWh_aVLGjEnO8zzIVs282edIsg3MRU,53453
sqlalchemy/sql/elements.py,sha256=WN5dGivh8ORfdG9fbkgyjmnHHiXn9eTRQEQILc9W828,181203
sqlalchemy/sql/events.py,sha256=07dXJLtV3G7I32BRdcqDoK_JNjHEWgz_wb3OKQr1h84,13413
sqlalchemy/sql/expression.py,sha256=ts3AukLIz196uvknRSm-DYC00BzMveWJx6UNyissn2Q,9106
sqlalchemy/sql/functions.py,sha256=RuWRLSA0xVLWDT5u05zw7miqZqSIuPB2HiDstFedkYo,48688
sqlalchemy/sql/lambdas.py,sha256=Rj6qqtxKIdFx8t7tWtC6aIDft1fZa7Yqlbucu1cWbkQ,44238
sqlalchemy/sql/naming.py,sha256=1aeTLfJRX6sOfkElOBbMhfw6je2k5j5_QZyjeluVtdQ,6996
sqlalchemy/sql/operators.py,sha256=xHZ122GiLU4BXYw8GRDCKYFQWqI1gxct5DqFzq1-YbA,49448
sqlalchemy/sql/roles.py,sha256=I9ru4yIN0gWcvwhydYcBwaLWnNcRVTtKqqq0b3m1kmM,5688
sqlalchemy/sql/schema.py,sha256=vqVRh2aVD84Oo34K4CpR51c0V1lus5qWkloC1NU-nEs,191715
sqlalchemy/sql/selectable.py,sha256=YZWef4rI8GhK_ICvkeJCLKBdQtCdEPi2iIOY-bonrUs,228277
sqlalchemy/sql/sqltypes.py,sha256=a0WERl0Fd4CkGB3KMPcdf7MnDdHNlNrU0TbzIlnTIds,114397
sqlalchemy/sql/traversals.py,sha256=eTRuqYptAJ33ihgLPizlc_S5m9zvKqC3V2t2YYtE6Fo,50825
sqlalchemy/sql/type_api.py,sha256=wtEMjCAdNBYhgqNvDSa1R8qdJ7Nodl7FVq9t8pmYL20,59373
sqlalchemy/sql/util.py,sha256=za_RUxIWNat5W90XzrRczIjKCk5LCP4CspT_30SF-7c,35545
sqlalchemy/sql/visitors.py,sha256=QoVBG8Yu5EsA1tKOq-rmM94jiFkma_6LNE0Ap92krWs,28065
sqlalchemy/testing/__init__.py,sha256=wLsdwby_EtsJioHMETDXxt-a72_SaLGO_Kv-oquS6Tc,2852
sqlalchemy/testing/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/testing/__pycache__/assertions.cpython-38.pyc,,
sqlalchemy/testing/__pycache__/assertsql.cpython-38.pyc,,
sqlalchemy/testing/__pycache__/asyncio.cpython-38.pyc,,
sqlalchemy/testing/__pycache__/config.cpython-38.pyc,,
sqlalchemy/testing/__pycache__/engines.cpython-38.pyc,,
sqlalchemy/testing/__pycache__/entities.cpython-38.pyc,,
sqlalchemy/testing/__pycache__/exclusions.cpython-38.pyc,,
sqlalchemy/testing/__pycache__/fixtures.cpython-38.pyc,,
sqlalchemy/testing/__pycache__/mock.cpython-38.pyc,,
sqlalchemy/testing/__pycache__/pickleable.cpython-38.pyc,,
sqlalchemy/testing/__pycache__/profiling.cpython-38.pyc,,
sqlalchemy/testing/__pycache__/provision.cpython-38.pyc,,
sqlalchemy/testing/__pycache__/requirements.cpython-38.pyc,,
sqlalchemy/testing/__pycache__/schema.cpython-38.pyc,,
sqlalchemy/testing/__pycache__/util.cpython-38.pyc,,
sqlalchemy/testing/__pycache__/warnings.cpython-38.pyc,,
sqlalchemy/testing/assertions.py,sha256=OECKIGe2UFuLMo-SaL8j8LCnWfVSbJ6ey2BCksdK4RA,24467
sqlalchemy/testing/assertsql.py,sha256=bIAionc7EQVbVOY8yUDUDdF-rdj5fEu_9HJlxPtH8A8,14690
sqlalchemy/testing/asyncio.py,sha256=oFYKzKstOnYTDdt9y_nRTgRciyYm1IsQ32sxmCPir9k,3801
sqlalchemy/testing/config.py,sha256=P2u5FCuHosOoaENchgTVOpRPG3JA2k5L-MBvyxGdz_g,6752
sqlalchemy/testing/engines.py,sha256=JHrKn2Yb9VK2jJZqQnysIoOQSERpYwHjDvJPN-bqSCQ,13099
sqlalchemy/testing/entities.py,sha256=sL_-R9UXbk0jw-76yIT2WieD0c8vTgfKFZDg3J7XMIc,3364
sqlalchemy/testing/exclusions.py,sha256=VW5TaRXawRdMSSIGxuC4N6Yyv1tNTpdkQE-W0m2frhw,13794
sqlalchemy/testing/fixtures.py,sha256=_r96TQmaRfQGboEzwEJAqgQezUZ0QHKiycje0fxFwYQ,25978
sqlalchemy/testing/mock.py,sha256=zGkRclR12c-9DI5Hu_kmt3oxnbk9qws7j0UxB5YjdBQ,926
sqlalchemy/testing/pickleable.py,sha256=RyI7y6HbY9_jAJNf-I2fceExCKihSm5JwbhLSEbGNys,2848
sqlalchemy/testing/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
sqlalchemy/testing/plugin/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/testing/plugin/__pycache__/bootstrap.cpython-38.pyc,,
sqlalchemy/testing/plugin/__pycache__/plugin_base.cpython-38.pyc,,
sqlalchemy/testing/plugin/__pycache__/pytestplugin.cpython-38.pyc,,
sqlalchemy/testing/plugin/__pycache__/reinvent_fixtures_py2k.cpython-38.pyc,,
sqlalchemy/testing/plugin/bootstrap.py,sha256=0104b_dYFUT5WsZU-NL44wlMo1LrKByBtPQYaFt6CTQ,1738
sqlalchemy/testing/plugin/plugin_base.py,sha256=A7EQMxsFDNmNeRZbSSzVFKzcNKT5dt7JsCY0rUu1Lv0,22350
sqlalchemy/testing/plugin/pytestplugin.py,sha256=Tj-wscMJ9yuPsS74U1AiJ-4UTrxNT-ZI89qHAAcv0-Y,24973
sqlalchemy/testing/plugin/reinvent_fixtures_py2k.py,sha256=b9fWp5RXdePykrNviZPXaGDIjOEOfovchez2Ovr4IRQ,3400
sqlalchemy/testing/profiling.py,sha256=4K-jOvPSRima5y6IQjnUwVwVAuwf2Ni8UaQMuFp8Q-Y,10901
sqlalchemy/testing/provision.py,sha256=J9PWi7i7Xmr-sALBrmK4OTXH9ur4rpFXKHhnhrjcQcs,12461
sqlalchemy/testing/requirements.py,sha256=fksdScqbp11oAAUAmuosAqDx9AOKmZCSpW68rz2SYWw,42210
sqlalchemy/testing/schema.py,sha256=xwGjcgGYJJH0fjbt3nw1FjfjJ4YU3NmLX3lfteW0oMk,6762
sqlalchemy/testing/suite/__init__.py,sha256=u3lEc0j47s7Dad_2SVWOZ6EU2aOMRWqE_WrQ17HmBsA,489
sqlalchemy/testing/suite/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/testing/suite/__pycache__/test_cte.cpython-38.pyc,,
sqlalchemy/testing/suite/__pycache__/test_ddl.cpython-38.pyc,,
sqlalchemy/testing/suite/__pycache__/test_deprecations.cpython-38.pyc,,
sqlalchemy/testing/suite/__pycache__/test_dialect.cpython-38.pyc,,
sqlalchemy/testing/suite/__pycache__/test_insert.cpython-38.pyc,,
sqlalchemy/testing/suite/__pycache__/test_reflection.cpython-38.pyc,,
sqlalchemy/testing/suite/__pycache__/test_results.cpython-38.pyc,,
sqlalchemy/testing/suite/__pycache__/test_rowcount.cpython-38.pyc,,
sqlalchemy/testing/suite/__pycache__/test_select.cpython-38.pyc,,
sqlalchemy/testing/suite/__pycache__/test_sequence.cpython-38.pyc,,
sqlalchemy/testing/suite/__pycache__/test_types.cpython-38.pyc,,
sqlalchemy/testing/suite/__pycache__/test_unicode_ddl.cpython-38.pyc,,
sqlalchemy/testing/suite/__pycache__/test_update_delete.cpython-38.pyc,,
sqlalchemy/testing/suite/test_cte.py,sha256=shi2WJZpzAzDCdkmzx0IDEu-URsLLBsdyFdzDqsfpyw,6387
sqlalchemy/testing/suite/test_ddl.py,sha256=BZuYkKaG_tNUkZcFLNd6o1qnfbzU0IYiedCw_NhOJBg,12143
sqlalchemy/testing/suite/test_deprecations.py,sha256=0LUmXIiK8hHUr6tY8cJJC7VErOj9YNGNN-c324k08Dw,5204
sqlalchemy/testing/suite/test_dialect.py,sha256=XpwZxIXlMVsZlP74khuPW2wZskinT0IOT9S6PM5PyE8,11256
sqlalchemy/testing/suite/test_insert.py,sha256=QlMovNeDU-GB5UvTEumce3LLK94PAduKlWe2TqCcLF4,11501
sqlalchemy/testing/suite/test_reflection.py,sha256=kZI4xcVR7_Ft_8kYYF58FjM7IIeuFzS0yXDj7lVfwbA,56815
sqlalchemy/testing/suite/test_results.py,sha256=qa_V37VKFRfi2xoI8d5bW9EzB_E_oPFhShBo9VPjCss,14396
sqlalchemy/testing/suite/test_rowcount.py,sha256=M6E-d4JuoVVfbBC-z59hB1accmoh4yARRJsD4yVFP60,4944
sqlalchemy/testing/suite/test_select.py,sha256=rjjXe3OT9ozjaLDLfTYVj5drKTPSZPJfjLrBqJzTCKk,54075
sqlalchemy/testing/suite/test_sequence.py,sha256=2KBcs0FtoL3gk37IN2PnRZSnQwt7RKkShAbYQHFTBcw,8713
sqlalchemy/testing/suite/test_types.py,sha256=jWuCiFEEJoTK79P9AhKsXilvf6AxLiy6THHw0NTGPxk,47037
sqlalchemy/testing/suite/test_unicode_ddl.py,sha256=HhAM4_38vpwJFX2d9xh0S_YAIQJQ-79GmfO3ich2Tu4,6943
sqlalchemy/testing/suite/test_update_delete.py,sha256=q3AoCPMKhxYVUi4n7YBjf8v8nb9obXmUXqnFsVxpZLY,1646
sqlalchemy/testing/util.py,sha256=QqaOSzP9UALgo17KTEb49cMfedShMg_wsIZNqyCkK6o,12961
sqlalchemy/testing/warnings.py,sha256=i3NM3HF9Oj83Q1otUhCujP_Py0bb4ZtTDUVK_I5_iik,5440
sqlalchemy/types.py,sha256=WSKKIhEFnXh7w7TfSYrCCZRmxol5y4GvRNNLZHn_YbU,2998
sqlalchemy/util/__init__.py,sha256=Ad93T5Xzn04K5Yb8Xg-iNaBrORh4TK9qXLyJI6Unks0,6435
sqlalchemy/util/__pycache__/__init__.cpython-38.pyc,,
sqlalchemy/util/__pycache__/_collections.cpython-38.pyc,,
sqlalchemy/util/__pycache__/_concurrency_py3k.cpython-38.pyc,,
sqlalchemy/util/__pycache__/_preloaded.cpython-38.pyc,,
sqlalchemy/util/__pycache__/compat.cpython-38.pyc,,
sqlalchemy/util/__pycache__/concurrency.cpython-38.pyc,,
sqlalchemy/util/__pycache__/deprecations.cpython-38.pyc,,
sqlalchemy/util/__pycache__/langhelpers.cpython-38.pyc,,
sqlalchemy/util/__pycache__/queue.cpython-38.pyc,,
sqlalchemy/util/__pycache__/topological.cpython-38.pyc,,
sqlalchemy/util/_collections.py,sha256=wmPLB-GxCASprLRAAKlcsWplJA_hcCA_nzDJefpTD98,30228
sqlalchemy/util/_concurrency_py3k.py,sha256=iE8ZnXzkIVXWIwR7In5bwIK1esv_vrlP2Nm2fhBose8,6728
sqlalchemy/util/_preloaded.py,sha256=g7_fB3j8aISY0wTtipzNJUy0S17jmNgHQtzSTL6QONQ,2464
sqlalchemy/util/compat.py,sha256=2UJp4PhIl-JGOsGQMCiPB2s4cCYkUGvGT8T9ZaDqPQE,18788
sqlalchemy/util/concurrency.py,sha256=tdD998NG1XOOC4m8Ml0mB2xuHzHy9UlVGMpNftMelbk,1826
sqlalchemy/util/deprecations.py,sha256=sTu_IGvp2vRoymZbMKT8wxoxL_wuZBXPs1Vd7uNISxw,11895
sqlalchemy/util/langhelpers.py,sha256=Omo4buzeJBpsepRM8emw_SwPihYxq8kGkEoySBF-xZk,58175
sqlalchemy/util/queue.py,sha256=nARh6EiML58Yie_tEE7KKvpEakV_aSRl16weYN8iRbs,9584
sqlalchemy/util/topological.py,sha256=S1MHtwgtiTcsHTbsxIet0ALX0jqjMfG0PHG7jrlyJ8g,2959

View File

@ -0,0 +1,5 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.36.2)
Root-Is-Purelib: false
Tag: cp38-cp38-win32

View File

@ -0,0 +1 @@
sqlalchemy

View File

@ -0,0 +1 @@
pip

View File

@ -0,0 +1,28 @@
Copyright 2007 Pallets
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,129 @@
Metadata-Version: 2.1
Name: Werkzeug
Version: 2.0.3
Summary: The comprehensive WSGI web application library.
Home-page: https://palletsprojects.com/p/werkzeug/
Author: Armin Ronacher
Author-email: armin.ronacher@active-4.com
Maintainer: Pallets
Maintainer-email: contact@palletsprojects.com
License: BSD-3-Clause
Project-URL: Donate, https://palletsprojects.com/donate
Project-URL: Documentation, https://werkzeug.palletsprojects.com/
Project-URL: Changes, https://werkzeug.palletsprojects.com/changes/
Project-URL: Source Code, https://github.com/pallets/werkzeug/
Project-URL: Issue Tracker, https://github.com/pallets/werkzeug/issues/
Project-URL: Twitter, https://twitter.com/PalletsTeam
Project-URL: Chat, https://discord.gg/pallets
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Requires-Python: >=3.6
Description-Content-Type: text/x-rst
License-File: LICENSE.rst
Requires-Dist: dataclasses ; python_version < "3.7"
Provides-Extra: watchdog
Requires-Dist: watchdog ; extra == 'watchdog'
Werkzeug
========
*werkzeug* German noun: "tool". Etymology: *werk* ("work"), *zeug* ("stuff")
Werkzeug is a comprehensive `WSGI`_ web application library. It began as
a simple collection of various utilities for WSGI applications and has
become one of the most advanced WSGI utility libraries.
It includes:
- An interactive debugger that allows inspecting stack traces and
source code in the browser with an interactive interpreter for any
frame in the stack.
- A full-featured request object with objects to interact with
headers, query args, form data, files, and cookies.
- A response object that can wrap other WSGI applications and handle
streaming data.
- A routing system for matching URLs to endpoints and generating URLs
for endpoints, with an extensible system for capturing variables
from URLs.
- HTTP utilities to handle entity tags, cache control, dates, user
agents, cookies, files, and more.
- A threaded WSGI server for use while developing applications
locally.
- A test client for simulating HTTP requests during testing without
requiring running a server.
Werkzeug doesn't enforce any dependencies. It is up to the developer to
choose a template engine, database adapter, and even how to handle
requests. It can be used to build all sorts of end user applications
such as blogs, wikis, or bulletin boards.
`Flask`_ wraps Werkzeug, using it to handle the details of WSGI while
providing more structure and patterns for defining powerful
applications.
.. _WSGI: https://wsgi.readthedocs.io/en/latest/
.. _Flask: https://www.palletsprojects.com/p/flask/
Installing
----------
Install and update using `pip`_:
.. code-block:: text
pip install -U Werkzeug
.. _pip: https://pip.pypa.io/en/stable/getting-started/
A Simple Example
----------------
.. code-block:: python
from werkzeug.wrappers import Request, Response
@Request.application
def application(request):
return Response('Hello, World!')
if __name__ == '__main__':
from werkzeug.serving import run_simple
run_simple('localhost', 4000, application)
Donate
------
The Pallets organization develops and supports Werkzeug and other
popular packages. In order to grow the community of contributors and
users, and allow the maintainers to devote more time to the projects,
`please donate today`_.
.. _please donate today: https://palletsprojects.com/donate
Links
-----
- Documentation: https://werkzeug.palletsprojects.com/
- Changes: https://werkzeug.palletsprojects.com/changes/
- PyPI Releases: https://pypi.org/project/Werkzeug/
- Source Code: https://github.com/pallets/werkzeug/
- Issue Tracker: https://github.com/pallets/werkzeug/issues/
- Website: https://palletsprojects.com/p/werkzeug/
- Twitter: https://twitter.com/PalletsTeam
- Chat: https://discord.gg/pallets

View File

@ -0,0 +1,112 @@
Werkzeug-2.0.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
Werkzeug-2.0.3.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475
Werkzeug-2.0.3.dist-info/METADATA,sha256=Rxzda7JFgpyr7oqR42Z57bNxRp-pjna_KYhcivqvXY4,4452
Werkzeug-2.0.3.dist-info/RECORD,,
Werkzeug-2.0.3.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
Werkzeug-2.0.3.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
Werkzeug-2.0.3.dist-info/top_level.txt,sha256=QRyj2VjwJoQkrwjwFIOlB8Xg3r9un0NtqVHQF-15xaw,9
werkzeug/__init__.py,sha256=2frslFsD2EbmZUTfzZ5njDmic66S5f6XMdT24AOGYhk,188
werkzeug/__pycache__/__init__.cpython-38.pyc,,
werkzeug/__pycache__/_internal.cpython-38.pyc,,
werkzeug/__pycache__/_reloader.cpython-38.pyc,,
werkzeug/__pycache__/datastructures.cpython-38.pyc,,
werkzeug/__pycache__/exceptions.cpython-38.pyc,,
werkzeug/__pycache__/filesystem.cpython-38.pyc,,
werkzeug/__pycache__/formparser.cpython-38.pyc,,
werkzeug/__pycache__/http.cpython-38.pyc,,
werkzeug/__pycache__/local.cpython-38.pyc,,
werkzeug/__pycache__/routing.cpython-38.pyc,,
werkzeug/__pycache__/security.cpython-38.pyc,,
werkzeug/__pycache__/serving.cpython-38.pyc,,
werkzeug/__pycache__/test.cpython-38.pyc,,
werkzeug/__pycache__/testapp.cpython-38.pyc,,
werkzeug/__pycache__/urls.cpython-38.pyc,,
werkzeug/__pycache__/user_agent.cpython-38.pyc,,
werkzeug/__pycache__/useragents.cpython-38.pyc,,
werkzeug/__pycache__/utils.cpython-38.pyc,,
werkzeug/__pycache__/wsgi.cpython-38.pyc,,
werkzeug/_internal.py,sha256=_0GZM3B6gE4eoRTp9K6T7spvY5qJQ9Od9GRIp4lZpzU,18572
werkzeug/_reloader.py,sha256=B1hEfgsUOz2IginBQM5Zak_eaIF7gr3GS5-0x2OHvAE,13950
werkzeug/datastructures.py,sha256=m79A8rHQEt5B7qVqyrjARXzHL66Katn8S92urGscTw4,97929
werkzeug/datastructures.pyi,sha256=uFOqffFoaOEa-43IPlK9otu1X4lDOoqIgG4ULS0ObiE,34119
werkzeug/debug/__init__.py,sha256=Vn0WQfD9w6DGg1j_2gWpSKKTaFlwxhbCBwi7QQMz1s8,17917
werkzeug/debug/__pycache__/__init__.cpython-38.pyc,,
werkzeug/debug/__pycache__/console.cpython-38.pyc,,
werkzeug/debug/__pycache__/repr.cpython-38.pyc,,
werkzeug/debug/__pycache__/tbtools.cpython-38.pyc,,
werkzeug/debug/console.py,sha256=jJjid1dIlCNWbDHXTtjJW5XqNfPjSOKbtUmEX5weNdY,5976
werkzeug/debug/repr.py,sha256=QCSHENKsChEZDCIApkVi_UNjhJ77v8BMXK1OfxO189M,9483
werkzeug/debug/shared/FONT_LICENSE,sha256=LwAVEI1oYnvXiNMT9SnCH_TaLCxCpeHziDrMg0gPkAI,4673
werkzeug/debug/shared/ICON_LICENSE.md,sha256=DhA6Y1gUl5Jwfg0NFN9Rj4VWITt8tUx0IvdGf0ux9-s,222
werkzeug/debug/shared/console.png,sha256=bxax6RXXlvOij_KeqvSNX0ojJf83YbnZ7my-3Gx9w2A,507
werkzeug/debug/shared/debugger.js,sha256=tg42SZs1SVmYWZ-_Fj5ELK5-FLHnGNQrei0K2By8Bw8,10521
werkzeug/debug/shared/less.png,sha256=-4-kNRaXJSONVLahrQKUxMwXGm9R4OnZ9SxDGpHlIR4,191
werkzeug/debug/shared/more.png,sha256=GngN7CioHQoV58rH6ojnkYi8c_qED2Aka5FO5UXrReY,200
werkzeug/debug/shared/source.png,sha256=RoGcBTE4CyCB85GBuDGTFlAnUqxwTBiIfDqW15EpnUQ,818
werkzeug/debug/shared/style.css,sha256=h1ZSUVaKNpfbfcYzRb513WAhPySGDQom1uih3uEDxPw,6704
werkzeug/debug/shared/ubuntu.ttf,sha256=1eaHFyepmy4FyDvjLVzpITrGEBu_CZYY94jE0nED1c0,70220
werkzeug/debug/tbtools.py,sha256=khUCWQcpbxzeOs5NlT-E9n99BI-ELH9K9RY5exc-X_o,19362
werkzeug/exceptions.py,sha256=WLCqXBEHm5Xj2d2sfON9XIneeRS3MlNXKH85k1AQIJU,28776
werkzeug/filesystem.py,sha256=JS2Dv2QF98WILxY4_thHl-WMcUcwluF_4igkDPaP1l4,1956
werkzeug/formparser.py,sha256=X-p3Ek4ji8XrKrbmaWxr8StLSc6iuksbpIeweaabs4s,17400
werkzeug/http.py,sha256=Xm3WhYKRQKh_J12514F8y8prILldXceOceeO8EiQEZI,45222
werkzeug/local.py,sha256=5HbGdD0vVNJgXH3SXfkMjdxIpzy7iqkHJMGCNjljFNo,23664
werkzeug/middleware/__init__.py,sha256=qfqgdT5npwG9ses3-FXQJf3aB95JYP1zchetH_T3PUw,500
werkzeug/middleware/__pycache__/__init__.cpython-38.pyc,,
werkzeug/middleware/__pycache__/dispatcher.cpython-38.pyc,,
werkzeug/middleware/__pycache__/http_proxy.cpython-38.pyc,,
werkzeug/middleware/__pycache__/lint.cpython-38.pyc,,
werkzeug/middleware/__pycache__/profiler.cpython-38.pyc,,
werkzeug/middleware/__pycache__/proxy_fix.cpython-38.pyc,,
werkzeug/middleware/__pycache__/shared_data.cpython-38.pyc,,
werkzeug/middleware/dispatcher.py,sha256=Fh_w-KyWnTSYF-Lfv5dimQ7THSS7afPAZMmvc4zF1gg,2580
werkzeug/middleware/http_proxy.py,sha256=HE8VyhS7CR-E1O6_9b68huv8FLgGGR1DLYqkS3Xcp3Q,7558
werkzeug/middleware/lint.py,sha256=sAg3GcOhICIkwYX5bJGG8n8iebX0Yipq_UH0HvrBvoU,13964
werkzeug/middleware/profiler.py,sha256=QkXk7cqnaPnF8wQu-5SyPCIOT3_kdABUBorQOghVNOA,4899
werkzeug/middleware/proxy_fix.py,sha256=l7LC_LDu0Yd4SvUxS5SFigAJMzcIOGm6LNKl9IXJBSU,6974
werkzeug/middleware/shared_data.py,sha256=xydEqOhAGg0aQJEllPDVfz2-8jHwWvJpAxfPsfPCu7k,10960
werkzeug/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
werkzeug/routing.py,sha256=rATL0ZkbTBgvdgJp6WgihuwKyivCF8K4a8kQ4hFgY6A,84581
werkzeug/sansio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
werkzeug/sansio/__pycache__/__init__.cpython-38.pyc,,
werkzeug/sansio/__pycache__/multipart.cpython-38.pyc,,
werkzeug/sansio/__pycache__/request.cpython-38.pyc,,
werkzeug/sansio/__pycache__/response.cpython-38.pyc,,
werkzeug/sansio/__pycache__/utils.cpython-38.pyc,,
werkzeug/sansio/multipart.py,sha256=BRjBk_mCPjSJzwNVvBgmrJGk3QxA9pYfsgzFki28bxc,8751
werkzeug/sansio/request.py,sha256=kt7fizz15HPuYKYU1_3TTEkNSuXeeaM4aLcjW84qvv4,20247
werkzeug/sansio/response.py,sha256=zvCq9HSBBZGBd5Gg412BY9RZIwnKsJl5Kzfd3Kl9sSo,26098
werkzeug/sansio/utils.py,sha256=V5v-UUnX8pm4RehP9Tt_NiUSOJGJGUvKjlW0eOIQldM,4164
werkzeug/security.py,sha256=gPDRuCjkjWrcqj99tBMq8_nHFZLFQjgoW5Ga5XIw9jo,8158
werkzeug/serving.py,sha256=6aV-RKbZm4rUHveQGuh4SY0wFZTmXyR43yD_kCQm8Wo,38287
werkzeug/test.py,sha256=eUORFaeIDXcmncLdYxgFqYiVdolZkYRY67QV1_ATk20,48235
werkzeug/testapp.py,sha256=f48prWSGJhbSrvYb8e1fnAah4BkrLb0enHSdChgsjBY,9471
werkzeug/urls.py,sha256=Du2lreBHvgBh5c2_bcx72g3hzV2ZabXYZsp-picUIJs,41023
werkzeug/user_agent.py,sha256=WclZhpvgLurMF45hsioSbS75H1Zb4iMQGKN3_yZ2oKo,1420
werkzeug/useragents.py,sha256=G8tmv_6vxJaPrLQH3eODNgIYe0_V6KETROQlJI-WxDE,7264
werkzeug/utils.py,sha256=D_dnCLUfodQ4k0GRSpnI6qDoVoaX7-Dza57bx7sabG0,37101
werkzeug/wrappers/__init__.py,sha256=-s75nPbyXHzU_rwmLPDhoMuGbEUk0jZT_n0ZQAOFGf8,654
werkzeug/wrappers/__pycache__/__init__.cpython-38.pyc,,
werkzeug/wrappers/__pycache__/accept.cpython-38.pyc,,
werkzeug/wrappers/__pycache__/auth.cpython-38.pyc,,
werkzeug/wrappers/__pycache__/base_request.cpython-38.pyc,,
werkzeug/wrappers/__pycache__/base_response.cpython-38.pyc,,
werkzeug/wrappers/__pycache__/common_descriptors.cpython-38.pyc,,
werkzeug/wrappers/__pycache__/cors.cpython-38.pyc,,
werkzeug/wrappers/__pycache__/etag.cpython-38.pyc,,
werkzeug/wrappers/__pycache__/json.cpython-38.pyc,,
werkzeug/wrappers/__pycache__/request.cpython-38.pyc,,
werkzeug/wrappers/__pycache__/response.cpython-38.pyc,,
werkzeug/wrappers/__pycache__/user_agent.cpython-38.pyc,,
werkzeug/wrappers/accept.py,sha256=NzyLfKH3qC5cSbkEc5azw5-lp_kU8JIrtc8AdGQ0HBs,413
werkzeug/wrappers/auth.py,sha256=ArJiEn8HHzy1B7wUGuN7s3AHpnClKlaDY0F7N7QZSLA,824
werkzeug/wrappers/base_request.py,sha256=saz9RyNQkvI_XLPYVm29KijNHmD1YzgxDqa0qHTbgss,1174
werkzeug/wrappers/base_response.py,sha256=q_-TaYywT5G4zA-DWDRDJhJSat2_4O7gOPob6ye4_9A,1186
werkzeug/wrappers/common_descriptors.py,sha256=aeVFTsTb0HJn5O8zF6WwELEDDULdOLFkWaUrvD1Huds,866
werkzeug/wrappers/cors.py,sha256=9Ho7aXd64sB2Msz71jRXAdAI8UyqIJgv-CJsnlfUSzM,814
werkzeug/wrappers/etag.py,sha256=7SI34rtlXJHyJlqe8B0dFu4ouo6L0DJmYyqwWoY79oc,814
werkzeug/wrappers/json.py,sha256=h_XfBZV5ZETkHYgONuoSyB9KXR9W90mgBh_mFUysp6c,394
werkzeug/wrappers/request.py,sha256=I77nwHgCzynmgwJVNw7bo7MfTU_CusNBO0b4TjpIRdQ,24790
werkzeug/wrappers/response.py,sha256=c24tBeq8G5RwPCU5iCJvJPaKyUEIrfMiWO4yGtTOwmI,35214
werkzeug/wrappers/user_agent.py,sha256=IMUJCFohZSMsBTmqyJZtjG5y4sB1zxQBE690bixb6uY,419
werkzeug/wsgi.py,sha256=L7s5-Rlt7BRVEZ1m81MaenGfMDP7yL3p1Kxt9Yssqzg,33727

View File

@ -0,0 +1,5 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.37.1)
Root-Is-Purelib: true
Tag: py3-none-any

View File

@ -0,0 +1 @@
werkzeug

View File

@ -0,0 +1 @@
pip

View File

@ -0,0 +1,19 @@
Copyright 2009-2025 Michael Bayer.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,143 @@
Metadata-Version: 2.2
Name: alembic
Version: 1.14.1
Summary: A database migration tool for SQLAlchemy.
Home-page: https://alembic.sqlalchemy.org
Author: Mike Bayer
Author-email: mike_mp@zzzcomputing.com
License: MIT
Project-URL: Documentation, https://alembic.sqlalchemy.org/en/latest/
Project-URL: Changelog, https://alembic.sqlalchemy.org/en/latest/changelog.html
Project-URL: Source, https://github.com/sqlalchemy/alembic/
Project-URL: Issue Tracker, https://github.com/sqlalchemy/alembic/issues/
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Environment :: Console
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Database :: Front-Ends
Requires-Python: >=3.8
Description-Content-Type: text/x-rst
License-File: LICENSE
Requires-Dist: SQLAlchemy>=1.3.0
Requires-Dist: Mako
Requires-Dist: importlib-metadata; python_version < "3.9"
Requires-Dist: importlib-resources; python_version < "3.9"
Requires-Dist: typing-extensions>=4
Provides-Extra: tz
Requires-Dist: backports.zoneinfo; python_version < "3.9" and extra == "tz"
Requires-Dist: tzdata; extra == "tz"
Alembic is a database migrations tool written by the author
of `SQLAlchemy <http://www.sqlalchemy.org>`_. A migrations tool
offers the following functionality:
* Can emit ALTER statements to a database in order to change
the structure of tables and other constructs
* Provides a system whereby "migration scripts" may be constructed;
each script indicates a particular series of steps that can "upgrade" a
target database to a new version, and optionally a series of steps that can
"downgrade" similarly, doing the same steps in reverse.
* Allows the scripts to execute in some sequential manner.
The goals of Alembic are:
* Very open ended and transparent configuration and operation. A new
Alembic environment is generated from a set of templates which is selected
among a set of options when setup first occurs. The templates then deposit a
series of scripts that define fully how database connectivity is established
and how migration scripts are invoked; the migration scripts themselves are
generated from a template within that series of scripts. The scripts can
then be further customized to define exactly how databases will be
interacted with and what structure new migration files should take.
* Full support for transactional DDL. The default scripts ensure that all
migrations occur within a transaction - for those databases which support
this (Postgresql, Microsoft SQL Server), migrations can be tested with no
need to manually undo changes upon failure.
* Minimalist script construction. Basic operations like renaming
tables/columns, adding/removing columns, changing column attributes can be
performed through one line commands like alter_column(), rename_table(),
add_constraint(). There is no need to recreate full SQLAlchemy Table
structures for simple operations like these - the functions themselves
generate minimalist schema structures behind the scenes to achieve the given
DDL sequence.
* "auto generation" of migrations. While real world migrations are far more
complex than what can be automatically determined, Alembic can still
eliminate the initial grunt work in generating new migration directives
from an altered schema. The ``--autogenerate`` feature will inspect the
current status of a database using SQLAlchemy's schema inspection
capabilities, compare it to the current state of the database model as
specified in Python, and generate a series of "candidate" migrations,
rendering them into a new migration script as Python directives. The
developer then edits the new file, adding additional directives and data
migrations as needed, to produce a finished migration. Table and column
level changes can be detected, with constraints and indexes to follow as
well.
* Full support for migrations generated as SQL scripts. Those of us who
work in corporate environments know that direct access to DDL commands on a
production database is a rare privilege, and DBAs want textual SQL scripts.
Alembic's usage model and commands are oriented towards being able to run a
series of migrations into a textual output file as easily as it runs them
directly to a database. Care must be taken in this mode to not invoke other
operations that rely upon in-memory SELECTs of rows - Alembic tries to
provide helper constructs like bulk_insert() to help with data-oriented
operations that are compatible with script-based DDL.
* Non-linear, dependency-graph versioning. Scripts are given UUID
identifiers similarly to a DVCS, and the linkage of one script to the next
is achieved via human-editable markers within the scripts themselves.
The structure of a set of migration files is considered as a
directed-acyclic graph, meaning any migration file can be dependent
on any other arbitrary set of migration files, or none at
all. Through this open-ended system, migration files can be organized
into branches, multiple roots, and mergepoints, without restriction.
Commands are provided to produce new branches, roots, and merges of
branches automatically.
* Provide a library of ALTER constructs that can be used by any SQLAlchemy
application. The DDL constructs build upon SQLAlchemy's own DDLElement base
and can be used standalone by any application or script.
* At long last, bring SQLite and its inability to ALTER things into the fold,
but in such a way that SQLite's very special workflow needs are accommodated
in an explicit way that makes the most of a bad situation, through the
concept of a "batch" migration, where multiple changes to a table can
be batched together to form a series of instructions for a single, subsequent
"move-and-copy" workflow. You can even use "move-and-copy" workflow for
other databases, if you want to recreate a table in the background
on a busy system.
Documentation and status of Alembic is at https://alembic.sqlalchemy.org/
The SQLAlchemy Project
======================
Alembic is part of the `SQLAlchemy Project <https://www.sqlalchemy.org>`_ and
adheres to the same standards and conventions as the core project.
Development / Bug reporting / Pull requests
___________________________________________
Please refer to the
`SQLAlchemy Community Guide <https://www.sqlalchemy.org/develop.html>`_ for
guidelines on coding and participating in this project.
Code of Conduct
_______________
Above all, SQLAlchemy places great emphasis on polite, thoughtful, and
constructive communication between users and developers.
Please see our current Code of Conduct at
`Code of Conduct <https://www.sqlalchemy.org/codeofconduct.html>`_.
License
=======
Alembic is distributed under the `MIT license
<https://opensource.org/licenses/MIT>`_.

View File

@ -0,0 +1,150 @@
../../Scripts/alembic.exe,sha256=24qCZ0mHldShV5Z-LZTiCspzR5wSmisB3Ga0_k2-W-4,98174
alembic-1.14.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
alembic-1.14.1.dist-info/LICENSE,sha256=NeqcNBmyYfrxvkSMT0fZJVKBv2s2tf_qVQUiJ9S6VN4,1059
alembic-1.14.1.dist-info/METADATA,sha256=D5AHibKWuwgPf9ORQhNm0k_iTmpKrkDNF-MboIrflY8,7420
alembic-1.14.1.dist-info/RECORD,,
alembic-1.14.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
alembic-1.14.1.dist-info/entry_points.txt,sha256=aykM30soxwGN0pB7etLc1q0cHJbL9dy46RnK9VX4LLw,48
alembic-1.14.1.dist-info/top_level.txt,sha256=FwKWd5VsPFC8iQjpu1u9Cn-JnK3-V1RhUCmWqz1cl-s,8
alembic/__init__.py,sha256=cdCZTWAIlk-sWQ6BPu9FEdV7AUyFJpTFU1bwmzWvqTo,63
alembic/__main__.py,sha256=373m7-TBh72JqrSMYviGrxCHZo-cnweM8AGF8A22PmY,78
alembic/__pycache__/__init__.cpython-38.pyc,,
alembic/__pycache__/__main__.cpython-38.pyc,,
alembic/__pycache__/command.cpython-38.pyc,,
alembic/__pycache__/config.cpython-38.pyc,,
alembic/__pycache__/context.cpython-38.pyc,,
alembic/__pycache__/environment.cpython-38.pyc,,
alembic/__pycache__/migration.cpython-38.pyc,,
alembic/__pycache__/op.cpython-38.pyc,,
alembic/autogenerate/__init__.py,sha256=ntmUTXhjLm4_zmqIwyVaECdpPDn6_u1yM9vYk6-553E,543
alembic/autogenerate/__pycache__/__init__.cpython-38.pyc,,
alembic/autogenerate/__pycache__/api.cpython-38.pyc,,
alembic/autogenerate/__pycache__/compare.cpython-38.pyc,,
alembic/autogenerate/__pycache__/render.cpython-38.pyc,,
alembic/autogenerate/__pycache__/rewriter.cpython-38.pyc,,
alembic/autogenerate/api.py,sha256=L4qkapSJO1Ypymx8HsjLl0vFFt202agwMYsQbIe6ZtI,22219
alembic/autogenerate/compare.py,sha256=cdUBH6qsedaJsnToSOu4MfcJaI4bjUJ4VWqtBlqsSr8,44944
alembic/autogenerate/render.py,sha256=JUjXpAmxhO-WPJGgvs0V_xtEC0Tpv0AngDepVfPIWUc,35482
alembic/autogenerate/rewriter.py,sha256=uZWRkTYJoncoEJ5WY1QBRiozjyChqZDJPy4LtcRibjM,7846
alembic/command.py,sha256=2tkKrIoEgPfXrGgvMRGrUXH4l-7z466DOxd7Q2XOfL8,22169
alembic/config.py,sha256=BZ7mwFRk2gq8GFNxxy9qvMUFx43YbDbQTC99OnjqiKY,22216
alembic/context.py,sha256=hK1AJOQXJ29Bhn276GYcosxeG7pC5aZRT5E8c4bMJ4Q,195
alembic/context.pyi,sha256=hUHbSnbSeEEMVkk0gDSXOq4_9edSjYzsjmmf-mL9Iao,31737
alembic/ddl/__init__.py,sha256=Df8fy4Vn_abP8B7q3x8gyFwEwnLw6hs2Ljt_bV3EZWE,152
alembic/ddl/__pycache__/__init__.cpython-38.pyc,,
alembic/ddl/__pycache__/_autogen.cpython-38.pyc,,
alembic/ddl/__pycache__/base.cpython-38.pyc,,
alembic/ddl/__pycache__/impl.cpython-38.pyc,,
alembic/ddl/__pycache__/mssql.cpython-38.pyc,,
alembic/ddl/__pycache__/mysql.cpython-38.pyc,,
alembic/ddl/__pycache__/oracle.cpython-38.pyc,,
alembic/ddl/__pycache__/postgresql.cpython-38.pyc,,
alembic/ddl/__pycache__/sqlite.cpython-38.pyc,,
alembic/ddl/_autogen.py,sha256=Blv2RrHNyF4cE6znCQXNXG5T9aO-YmiwD4Fz-qfoaWA,9275
alembic/ddl/base.py,sha256=gazpvtk_6XURcsa0libwcaIquL5HwJDP1ZWKJ6P7x0I,9788
alembic/ddl/impl.py,sha256=7-oxMb7KeycaK96x-kXw4mR6NSE1tmN0UEZIZrPcuhY,30195
alembic/ddl/mssql.py,sha256=ydvgBSaftKYjaBaMyqius66Ta4CICQSj79Og3Ed2atY,14219
alembic/ddl/mysql.py,sha256=kXOGYmpnL_9WL3ijXNsG4aAwy3m1HWJOoLZSePzmJF0,17316
alembic/ddl/oracle.py,sha256=669YlkcZihlXFbnXhH2krdrvDry8q5pcUGfoqkg_R6Y,6243
alembic/ddl/postgresql.py,sha256=OR9ufFDr-uvzIBk38OBsLlfr_PXG9qBSDYIj0-oNnwc,29921
alembic/ddl/sqlite.py,sha256=yR1ov010h3HIpJvZbCLTkR7HIkKQMfEAGJE7ZnLwmSU,7980
alembic/environment.py,sha256=MM5lPayGT04H3aeng1H7GQ8HEAs3VGX5yy6mDLCPLT4,43
alembic/migration.py,sha256=MV6Fju6rZtn2fTREKzXrCZM6aIBGII4OMZFix0X-GLs,41
alembic/op.py,sha256=flHtcsVqOD-ZgZKK2pv-CJ5Cwh-KJ7puMUNXzishxLw,167
alembic/op.pyi,sha256=QZ1ERetxIrpZNTyg48Btn5OJhhpMId-_MLMP36RauOw,50168
alembic/operations/__init__.py,sha256=e0KQSZAgLpTWvyvreB7DWg7RJV_MWSOPVDgCqsd2FzY,318
alembic/operations/__pycache__/__init__.cpython-38.pyc,,
alembic/operations/__pycache__/base.cpython-38.pyc,,
alembic/operations/__pycache__/batch.cpython-38.pyc,,
alembic/operations/__pycache__/ops.cpython-38.pyc,,
alembic/operations/__pycache__/schemaobj.cpython-38.pyc,,
alembic/operations/__pycache__/toimpl.cpython-38.pyc,,
alembic/operations/base.py,sha256=JRaOtPqyqfaPjzGHxuP9VMcO1KsJNmbbLOvwG82qxGA,74474
alembic/operations/batch.py,sha256=YqtD4hJ3_RkFxvI7zbmBwxcLEyLHYyWQpsz4l5L85yI,26943
alembic/operations/ops.py,sha256=guIpLQzlqgkdP2LGDW8vWg_DXeAouEldiVZDgRas7YI,94953
alembic/operations/schemaobj.py,sha256=Wp-bBe4a8lXPTvIHJttBY0ejtpVR5Jvtb2kI-U2PztQ,9468
alembic/operations/toimpl.py,sha256=Fx-UKcq6S8pVtsEwPFjTKtEcAVKjfptn-BfpE1k3_ck,7517
alembic/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
alembic/runtime/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
alembic/runtime/__pycache__/__init__.cpython-38.pyc,,
alembic/runtime/__pycache__/environment.cpython-38.pyc,,
alembic/runtime/__pycache__/migration.cpython-38.pyc,,
alembic/runtime/environment.py,sha256=SkYB_am1h3FSG8IsExAQxGP_7WwzOVigqjlO747Aokc,41497
alembic/runtime/migration.py,sha256=9GZ_bYZ6yMF7DUD1hgZdmB0YqvcdcNBBfxFaXKHeQoM,49857
alembic/script/__init__.py,sha256=lSj06O391Iy5avWAiq8SPs6N8RBgxkSPjP8wpXcNDGg,100
alembic/script/__pycache__/__init__.cpython-38.pyc,,
alembic/script/__pycache__/base.cpython-38.pyc,,
alembic/script/__pycache__/revision.cpython-38.pyc,,
alembic/script/__pycache__/write_hooks.cpython-38.pyc,,
alembic/script/base.py,sha256=XLNpdsLnBBSz4ZKMFUArFUdtL1HcjtuUDHNbA-5VlZA,37809
alembic/script/revision.py,sha256=NTu-eu5Y78u4NoVXpT0alpD2oL40SGATA2sEMEf1el4,62306
alembic/script/write_hooks.py,sha256=NGB6NGgfdf7HK6XNNpSKqUCfzxazj-NRUePgFx7MJSM,5036
alembic/templates/async/README,sha256=ISVtAOvqvKk_5ThM5ioJE-lMkvf9IbknFUFVU_vPma4,58
alembic/templates/async/__pycache__/env.cpython-38.pyc,,
alembic/templates/async/alembic.ini.mako,sha256=lYN5fP_fIX3FWtTcOy86Xznr6P5r1f0rlkdDhxLhVN4,3658
alembic/templates/async/env.py,sha256=zbOCf3Y7w2lg92hxSwmG1MM_7y56i_oRH4AKp0pQBYo,2389
alembic/templates/async/script.py.mako,sha256=MEqL-2qATlST9TAOeYgscMn1uy6HUS9NFvDgl93dMj8,635
alembic/templates/generic/README,sha256=MVlc9TYmr57RbhXET6QxgyCcwWP7w-vLkEsirENqiIQ,38
alembic/templates/generic/__pycache__/env.cpython-38.pyc,,
alembic/templates/generic/alembic.ini.mako,sha256=TPnqGqwg9QG8uCvBY5jaz32U2pqVqLK1dG1e8i2yDYM,3766
alembic/templates/generic/env.py,sha256=TLRWOVW3Xpt_Tpf8JFzlnoPn_qoUu8UV77Y4o9XD6yI,2103
alembic/templates/generic/script.py.mako,sha256=MEqL-2qATlST9TAOeYgscMn1uy6HUS9NFvDgl93dMj8,635
alembic/templates/multidb/README,sha256=dWLDhnBgphA4Nzb7sNlMfCS3_06YqVbHhz-9O5JNqyI,606
alembic/templates/multidb/__pycache__/env.cpython-38.pyc,,
alembic/templates/multidb/alembic.ini.mako,sha256=cVrikS0KRB46GVcjSO8xKYm7rqUngqTnd06pCozm1Pw,3860
alembic/templates/multidb/env.py,sha256=6zNjnW8mXGUk7erTsAvrfhvqoczJ-gagjVq1Ypg2YIQ,4230
alembic/templates/multidb/script.py.mako,sha256=N06nMtNSwHkgl0EBXDyMt8njp9tlOesR583gfq21nbY,1090
alembic/testing/__init__.py,sha256=kOxOh5nwmui9d-_CCq9WA4Udwy7ITjm453w74CTLZDo,1159
alembic/testing/__pycache__/__init__.cpython-38.pyc,,
alembic/testing/__pycache__/assertions.cpython-38.pyc,,
alembic/testing/__pycache__/env.cpython-38.pyc,,
alembic/testing/__pycache__/fixtures.cpython-38.pyc,,
alembic/testing/__pycache__/requirements.cpython-38.pyc,,
alembic/testing/__pycache__/schemacompare.cpython-38.pyc,,
alembic/testing/__pycache__/util.cpython-38.pyc,,
alembic/testing/__pycache__/warnings.cpython-38.pyc,,
alembic/testing/assertions.py,sha256=ScUb1sVopIl70BirfHUJDvwswC70Q93CiIWwkiZbhHg,5207
alembic/testing/env.py,sha256=giHWVLhHkfNWrPEfrAqhpMOLL6FgWoBCVAzBVrVbSSA,10766
alembic/testing/fixtures.py,sha256=nBntOynOmVCFc7IYiN3DIQ3TBNTfiGCvL_1-FyCry8o,9462
alembic/testing/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
alembic/testing/plugin/__pycache__/__init__.cpython-38.pyc,,
alembic/testing/plugin/__pycache__/bootstrap.cpython-38.pyc,,
alembic/testing/plugin/bootstrap.py,sha256=9C6wtjGrIVztZ928w27hsQE0KcjDLIUtUN3dvZKsMVk,50
alembic/testing/requirements.py,sha256=dKeAO1l5TwBqXarJN-IPORlCqCJv-41Dj6oXoEikxHQ,5133
alembic/testing/schemacompare.py,sha256=N5UqSNCOJetIKC4vKhpYzQEpj08XkdgIoqBmEPQ3tlc,4838
alembic/testing/suite/__init__.py,sha256=MvE7-hwbaVN1q3NM-ztGxORU9dnIelUCINKqNxewn7Y,288
alembic/testing/suite/__pycache__/__init__.cpython-38.pyc,,
alembic/testing/suite/__pycache__/_autogen_fixtures.cpython-38.pyc,,
alembic/testing/suite/__pycache__/test_autogen_comments.cpython-38.pyc,,
alembic/testing/suite/__pycache__/test_autogen_computed.cpython-38.pyc,,
alembic/testing/suite/__pycache__/test_autogen_diffs.cpython-38.pyc,,
alembic/testing/suite/__pycache__/test_autogen_fks.cpython-38.pyc,,
alembic/testing/suite/__pycache__/test_autogen_identity.cpython-38.pyc,,
alembic/testing/suite/__pycache__/test_environment.cpython-38.pyc,,
alembic/testing/suite/__pycache__/test_op.cpython-38.pyc,,
alembic/testing/suite/_autogen_fixtures.py,sha256=cDq1pmzHe15S6dZPGNC6sqFaCQ3hLT_oPV2IDigUGQ0,9880
alembic/testing/suite/test_autogen_comments.py,sha256=aEGqKUDw4kHjnDk298aoGcQvXJWmZXcIX_2FxH4cJK8,6283
alembic/testing/suite/test_autogen_computed.py,sha256=CXAeF-5Wr2cmW8PB7ztHG_4ZQsn1gSWrHWfxi72grNU,6147
alembic/testing/suite/test_autogen_diffs.py,sha256=T4SR1n_kmcOKYhR4W1-dA0e5sddJ69DSVL2HW96kAkE,8394
alembic/testing/suite/test_autogen_fks.py,sha256=AqFmb26Buex167HYa9dZWOk8x-JlB1OK3bwcvvjDFaU,32927
alembic/testing/suite/test_autogen_identity.py,sha256=kcuqngG7qXAKPJDX4U8sRzPKHEJECHuZ0DtuaS6tVkk,5824
alembic/testing/suite/test_environment.py,sha256=OwD-kpESdLoc4byBrGrXbZHvqtPbzhFCG4W9hJOJXPQ,11877
alembic/testing/suite/test_op.py,sha256=2XQCdm_NmnPxHGuGj7hmxMzIhKxXNotUsKdACXzE1mM,1343
alembic/testing/util.py,sha256=CQrcQDA8fs_7ME85z5ydb-Bt70soIIID-qNY1vbR2dg,3350
alembic/testing/warnings.py,sha256=RxA7x_8GseANgw07Us8JN_1iGbANxaw6_VitX2ZGQH4,1078
alembic/util/__init__.py,sha256=KSZ7UT2YzH6CietgUtljVoE3QnGjoFKOi7RL5sgUxrk,1688
alembic/util/__pycache__/__init__.cpython-38.pyc,,
alembic/util/__pycache__/compat.cpython-38.pyc,,
alembic/util/__pycache__/editor.cpython-38.pyc,,
alembic/util/__pycache__/exc.cpython-38.pyc,,
alembic/util/__pycache__/langhelpers.cpython-38.pyc,,
alembic/util/__pycache__/messaging.cpython-38.pyc,,
alembic/util/__pycache__/pyfiles.cpython-38.pyc,,
alembic/util/__pycache__/sqla_compat.cpython-38.pyc,,
alembic/util/compat.py,sha256=eoR9ReCTV_l0xGgGlr_OJmVvJecttBYXRKfDhoK8zKU,2630
alembic/util/editor.py,sha256=JIz6_BdgV8_oKtnheR6DZoB7qnrHrlRgWjx09AsTsUw,2546
alembic/util/exc.py,sha256=KQTru4zcgAmN4IxLMwLFS56XToUewaXB7oOLcPNjPwg,98
alembic/util/langhelpers.py,sha256=LpOcovnhMnP45kTt8zNJ4BHpyQrlF40OL6yDXjqKtsE,10026
alembic/util/messaging.py,sha256=BxAHiJsYHBPb2m8zv4yaueSRAlVuYXWkRCeN02JXhqw,3250
alembic/util/pyfiles.py,sha256=zltVdcwEJJCPS2gHsQvkHkQakuF6wXiZ6zfwHbGNT0g,3489
alembic/util/sqla_compat.py,sha256=XMfZaLdbVbJoniNUyI3RUUXu4gCWljjVBbJ7db6vCgc,19526

View File

@ -0,0 +1,5 @@
Wheel-Version: 1.0
Generator: setuptools (75.8.0)
Root-Is-Purelib: true
Tag: py3-none-any

View File

@ -0,0 +1,2 @@
[console_scripts]
alembic = alembic.config:main

View File

@ -0,0 +1 @@
alembic

View File

@ -0,0 +1,4 @@
from . import context
from . import op
__version__ = "1.14.1"

View File

@ -0,0 +1,4 @@
from .config import main
if __name__ == "__main__":
main(prog="alembic")

View File

@ -0,0 +1,10 @@
from .api import _render_migration_diffs as _render_migration_diffs
from .api import compare_metadata as compare_metadata
from .api import produce_migrations as produce_migrations
from .api import render_python_code as render_python_code
from .api import RevisionContext as RevisionContext
from .compare import _produce_net_changes as _produce_net_changes
from .compare import comparators as comparators
from .render import render_op_text as render_op_text
from .render import renderers as renderers
from .rewriter import Rewriter as Rewriter

View File

@ -0,0 +1,650 @@
from __future__ import annotations
import contextlib
from typing import Any
from typing import Dict
from typing import Iterator
from typing import List
from typing import Optional
from typing import Sequence
from typing import Set
from typing import TYPE_CHECKING
from typing import Union
from sqlalchemy import inspect
from . import compare
from . import render
from .. import util
from ..operations import ops
from ..util import sqla_compat
"""Provide the 'autogenerate' feature which can produce migration operations
automatically."""
if TYPE_CHECKING:
from sqlalchemy.engine import Connection
from sqlalchemy.engine import Dialect
from sqlalchemy.engine import Inspector
from sqlalchemy.sql.schema import MetaData
from sqlalchemy.sql.schema import SchemaItem
from sqlalchemy.sql.schema import Table
from ..config import Config
from ..operations.ops import DowngradeOps
from ..operations.ops import MigrationScript
from ..operations.ops import UpgradeOps
from ..runtime.environment import NameFilterParentNames
from ..runtime.environment import NameFilterType
from ..runtime.environment import ProcessRevisionDirectiveFn
from ..runtime.environment import RenderItemFn
from ..runtime.migration import MigrationContext
from ..script.base import Script
from ..script.base import ScriptDirectory
from ..script.revision import _GetRevArg
def compare_metadata(context: MigrationContext, metadata: MetaData) -> Any:
"""Compare a database schema to that given in a
:class:`~sqlalchemy.schema.MetaData` instance.
The database connection is presented in the context
of a :class:`.MigrationContext` object, which
provides database connectivity as well as optional
comparison functions to use for datatypes and
server defaults - see the "autogenerate" arguments
at :meth:`.EnvironmentContext.configure`
for details on these.
The return format is a list of "diff" directives,
each representing individual differences::
from alembic.migration import MigrationContext
from alembic.autogenerate import compare_metadata
from sqlalchemy import (
create_engine,
MetaData,
Column,
Integer,
String,
Table,
text,
)
import pprint
engine = create_engine("sqlite://")
with engine.begin() as conn:
conn.execute(
text(
'''
create table foo (
id integer not null primary key,
old_data varchar,
x integer
)
'''
)
)
conn.execute(text("create table bar (data varchar)"))
metadata = MetaData()
Table(
"foo",
metadata,
Column("id", Integer, primary_key=True),
Column("data", Integer),
Column("x", Integer, nullable=False),
)
Table("bat", metadata, Column("info", String))
mc = MigrationContext.configure(engine.connect())
diff = compare_metadata(mc, metadata)
pprint.pprint(diff, indent=2, width=20)
Output::
[
(
"add_table",
Table(
"bat",
MetaData(),
Column("info", String(), table=<bat>),
schema=None,
),
),
(
"remove_table",
Table(
"bar",
MetaData(),
Column("data", VARCHAR(), table=<bar>),
schema=None,
),
),
(
"add_column",
None,
"foo",
Column("data", Integer(), table=<foo>),
),
[
(
"modify_nullable",
None,
"foo",
"x",
{
"existing_comment": None,
"existing_server_default": False,
"existing_type": INTEGER(),
},
True,
False,
)
],
(
"remove_column",
None,
"foo",
Column("old_data", VARCHAR(), table=<foo>),
),
]
:param context: a :class:`.MigrationContext`
instance.
:param metadata: a :class:`~sqlalchemy.schema.MetaData`
instance.
.. seealso::
:func:`.produce_migrations` - produces a :class:`.MigrationScript`
structure based on metadata comparison.
"""
migration_script = produce_migrations(context, metadata)
assert migration_script.upgrade_ops is not None
return migration_script.upgrade_ops.as_diffs()
def produce_migrations(
context: MigrationContext, metadata: MetaData
) -> MigrationScript:
"""Produce a :class:`.MigrationScript` structure based on schema
comparison.
This function does essentially what :func:`.compare_metadata` does,
but then runs the resulting list of diffs to produce the full
:class:`.MigrationScript` object. For an example of what this looks like,
see the example in :ref:`customizing_revision`.
.. seealso::
:func:`.compare_metadata` - returns more fundamental "diff"
data from comparing a schema.
"""
autogen_context = AutogenContext(context, metadata=metadata)
migration_script = ops.MigrationScript(
rev_id=None,
upgrade_ops=ops.UpgradeOps([]),
downgrade_ops=ops.DowngradeOps([]),
)
compare._populate_migration_script(autogen_context, migration_script)
return migration_script
def render_python_code(
up_or_down_op: Union[UpgradeOps, DowngradeOps],
sqlalchemy_module_prefix: str = "sa.",
alembic_module_prefix: str = "op.",
render_as_batch: bool = False,
imports: Sequence[str] = (),
render_item: Optional[RenderItemFn] = None,
migration_context: Optional[MigrationContext] = None,
user_module_prefix: Optional[str] = None,
) -> str:
"""Render Python code given an :class:`.UpgradeOps` or
:class:`.DowngradeOps` object.
This is a convenience function that can be used to test the
autogenerate output of a user-defined :class:`.MigrationScript` structure.
:param up_or_down_op: :class:`.UpgradeOps` or :class:`.DowngradeOps` object
:param sqlalchemy_module_prefix: module prefix for SQLAlchemy objects
:param alembic_module_prefix: module prefix for Alembic constructs
:param render_as_batch: use "batch operations" style for rendering
:param imports: sequence of import symbols to add
:param render_item: callable to render items
:param migration_context: optional :class:`.MigrationContext`
:param user_module_prefix: optional string prefix for user-defined types
.. versionadded:: 1.11.0
"""
opts = {
"sqlalchemy_module_prefix": sqlalchemy_module_prefix,
"alembic_module_prefix": alembic_module_prefix,
"render_item": render_item,
"render_as_batch": render_as_batch,
"user_module_prefix": user_module_prefix,
}
if migration_context is None:
from ..runtime.migration import MigrationContext
from sqlalchemy.engine.default import DefaultDialect
migration_context = MigrationContext.configure(
dialect=DefaultDialect()
)
autogen_context = AutogenContext(migration_context, opts=opts)
autogen_context.imports = set(imports)
return render._indent(
render._render_cmd_body(up_or_down_op, autogen_context)
)
def _render_migration_diffs(
context: MigrationContext, template_args: Dict[Any, Any]
) -> None:
"""legacy, used by test_autogen_composition at the moment"""
autogen_context = AutogenContext(context)
upgrade_ops = ops.UpgradeOps([])
compare._produce_net_changes(autogen_context, upgrade_ops)
migration_script = ops.MigrationScript(
rev_id=None,
upgrade_ops=upgrade_ops,
downgrade_ops=upgrade_ops.reverse(),
)
render._render_python_into_templatevars(
autogen_context, migration_script, template_args
)
class AutogenContext:
"""Maintains configuration and state that's specific to an
autogenerate operation."""
metadata: Union[MetaData, Sequence[MetaData], None] = None
"""The :class:`~sqlalchemy.schema.MetaData` object
representing the destination.
This object is the one that is passed within ``env.py``
to the :paramref:`.EnvironmentContext.configure.target_metadata`
parameter. It represents the structure of :class:`.Table` and other
objects as stated in the current database model, and represents the
destination structure for the database being examined.
While the :class:`~sqlalchemy.schema.MetaData` object is primarily
known as a collection of :class:`~sqlalchemy.schema.Table` objects,
it also has an :attr:`~sqlalchemy.schema.MetaData.info` dictionary
that may be used by end-user schemes to store additional schema-level
objects that are to be compared in custom autogeneration schemes.
"""
connection: Optional[Connection] = None
"""The :class:`~sqlalchemy.engine.base.Connection` object currently
connected to the database backend being compared.
This is obtained from the :attr:`.MigrationContext.bind` and is
ultimately set up in the ``env.py`` script.
"""
dialect: Optional[Dialect] = None
"""The :class:`~sqlalchemy.engine.Dialect` object currently in use.
This is normally obtained from the
:attr:`~sqlalchemy.engine.base.Connection.dialect` attribute.
"""
imports: Set[str] = None # type: ignore[assignment]
"""A ``set()`` which contains string Python import directives.
The directives are to be rendered into the ``${imports}`` section
of a script template. The set is normally empty and can be modified
within hooks such as the
:paramref:`.EnvironmentContext.configure.render_item` hook.
.. seealso::
:ref:`autogen_render_types`
"""
migration_context: MigrationContext = None # type: ignore[assignment]
"""The :class:`.MigrationContext` established by the ``env.py`` script."""
def __init__(
self,
migration_context: MigrationContext,
metadata: Union[MetaData, Sequence[MetaData], None] = None,
opts: Optional[Dict[str, Any]] = None,
autogenerate: bool = True,
) -> None:
if (
autogenerate
and migration_context is not None
and migration_context.as_sql
):
raise util.CommandError(
"autogenerate can't use as_sql=True as it prevents querying "
"the database for schema information"
)
if opts is None:
opts = migration_context.opts
self.metadata = metadata = (
opts.get("target_metadata", None) if metadata is None else metadata
)
if (
autogenerate
and metadata is None
and migration_context is not None
and migration_context.script is not None
):
raise util.CommandError(
"Can't proceed with --autogenerate option; environment "
"script %s does not provide "
"a MetaData object or sequence of objects to the context."
% (migration_context.script.env_py_location)
)
include_object = opts.get("include_object", None)
include_name = opts.get("include_name", None)
object_filters = []
name_filters = []
if include_object:
object_filters.append(include_object)
if include_name:
name_filters.append(include_name)
self._object_filters = object_filters
self._name_filters = name_filters
self.migration_context = migration_context
if self.migration_context is not None:
self.connection = self.migration_context.bind
self.dialect = self.migration_context.dialect
self.imports = set()
self.opts: Dict[str, Any] = opts
self._has_batch: bool = False
@util.memoized_property
def inspector(self) -> Inspector:
if self.connection is None:
raise TypeError(
"can't return inspector as this "
"AutogenContext has no database connection"
)
return inspect(self.connection)
@contextlib.contextmanager
def _within_batch(self) -> Iterator[None]:
self._has_batch = True
yield
self._has_batch = False
def run_name_filters(
self,
name: Optional[str],
type_: NameFilterType,
parent_names: NameFilterParentNames,
) -> bool:
"""Run the context's name filters and return True if the targets
should be part of the autogenerate operation.
This method should be run for every kind of name encountered within the
reflection side of an autogenerate operation, giving the environment
the chance to filter what names should be reflected as database
objects. The filters here are produced directly via the
:paramref:`.EnvironmentContext.configure.include_name` parameter.
"""
if "schema_name" in parent_names:
if type_ == "table":
table_name = name
else:
table_name = parent_names.get("table_name", None)
if table_name:
schema_name = parent_names["schema_name"]
if schema_name:
parent_names["schema_qualified_table_name"] = "%s.%s" % (
schema_name,
table_name,
)
else:
parent_names["schema_qualified_table_name"] = table_name
for fn in self._name_filters:
if not fn(name, type_, parent_names):
return False
else:
return True
def run_object_filters(
self,
object_: SchemaItem,
name: sqla_compat._ConstraintName,
type_: NameFilterType,
reflected: bool,
compare_to: Optional[SchemaItem],
) -> bool:
"""Run the context's object filters and return True if the targets
should be part of the autogenerate operation.
This method should be run for every kind of object encountered within
an autogenerate operation, giving the environment the chance
to filter what objects should be included in the comparison.
The filters here are produced directly via the
:paramref:`.EnvironmentContext.configure.include_object` parameter.
"""
for fn in self._object_filters:
if not fn(object_, name, type_, reflected, compare_to):
return False
else:
return True
run_filters = run_object_filters
@util.memoized_property
def sorted_tables(self) -> List[Table]:
"""Return an aggregate of the :attr:`.MetaData.sorted_tables`
collection(s).
For a sequence of :class:`.MetaData` objects, this
concatenates the :attr:`.MetaData.sorted_tables` collection
for each individual :class:`.MetaData` in the order of the
sequence. It does **not** collate the sorted tables collections.
"""
result = []
for m in util.to_list(self.metadata):
result.extend(m.sorted_tables)
return result
@util.memoized_property
def table_key_to_table(self) -> Dict[str, Table]:
"""Return an aggregate of the :attr:`.MetaData.tables` dictionaries.
The :attr:`.MetaData.tables` collection is a dictionary of table key
to :class:`.Table`; this method aggregates the dictionary across
multiple :class:`.MetaData` objects into one dictionary.
Duplicate table keys are **not** supported; if two :class:`.MetaData`
objects contain the same table key, an exception is raised.
"""
result: Dict[str, Table] = {}
for m in util.to_list(self.metadata):
intersect = set(result).intersection(set(m.tables))
if intersect:
raise ValueError(
"Duplicate table keys across multiple "
"MetaData objects: %s"
% (", ".join('"%s"' % key for key in sorted(intersect)))
)
result.update(m.tables)
return result
class RevisionContext:
"""Maintains configuration and state that's specific to a revision
file generation operation."""
generated_revisions: List[MigrationScript]
process_revision_directives: Optional[ProcessRevisionDirectiveFn]
def __init__(
self,
config: Config,
script_directory: ScriptDirectory,
command_args: Dict[str, Any],
process_revision_directives: Optional[
ProcessRevisionDirectiveFn
] = None,
) -> None:
self.config = config
self.script_directory = script_directory
self.command_args = command_args
self.process_revision_directives = process_revision_directives
self.template_args = {
"config": config # Let templates use config for
# e.g. multiple databases
}
self.generated_revisions = [self._default_revision()]
def _to_script(
self, migration_script: MigrationScript
) -> Optional[Script]:
template_args: Dict[str, Any] = self.template_args.copy()
if getattr(migration_script, "_needs_render", False):
autogen_context = self._last_autogen_context
# clear out existing imports if we are doing multiple
# renders
autogen_context.imports = set()
if migration_script.imports:
autogen_context.imports.update(migration_script.imports)
render._render_python_into_templatevars(
autogen_context, migration_script, template_args
)
assert migration_script.rev_id is not None
return self.script_directory.generate_revision(
migration_script.rev_id,
migration_script.message,
refresh=True,
head=migration_script.head,
splice=migration_script.splice,
branch_labels=migration_script.branch_label,
version_path=migration_script.version_path,
depends_on=migration_script.depends_on,
**template_args,
)
def run_autogenerate(
self, rev: _GetRevArg, migration_context: MigrationContext
) -> None:
self._run_environment(rev, migration_context, True)
def run_no_autogenerate(
self, rev: _GetRevArg, migration_context: MigrationContext
) -> None:
self._run_environment(rev, migration_context, False)
def _run_environment(
self,
rev: _GetRevArg,
migration_context: MigrationContext,
autogenerate: bool,
) -> None:
if autogenerate:
if self.command_args["sql"]:
raise util.CommandError(
"Using --sql with --autogenerate does not make any sense"
)
if set(self.script_directory.get_revisions(rev)) != set(
self.script_directory.get_revisions("heads")
):
raise util.CommandError("Target database is not up to date.")
upgrade_token = migration_context.opts["upgrade_token"]
downgrade_token = migration_context.opts["downgrade_token"]
migration_script = self.generated_revisions[-1]
if not getattr(migration_script, "_needs_render", False):
migration_script.upgrade_ops_list[-1].upgrade_token = upgrade_token
migration_script.downgrade_ops_list[-1].downgrade_token = (
downgrade_token
)
migration_script._needs_render = True
else:
migration_script._upgrade_ops.append(
ops.UpgradeOps([], upgrade_token=upgrade_token)
)
migration_script._downgrade_ops.append(
ops.DowngradeOps([], downgrade_token=downgrade_token)
)
autogen_context = AutogenContext(
migration_context, autogenerate=autogenerate
)
self._last_autogen_context: AutogenContext = autogen_context
if autogenerate:
compare._populate_migration_script(
autogen_context, migration_script
)
if self.process_revision_directives:
self.process_revision_directives(
migration_context, rev, self.generated_revisions
)
hook = migration_context.opts["process_revision_directives"]
if hook:
hook(migration_context, rev, self.generated_revisions)
for migration_script in self.generated_revisions:
migration_script._needs_render = True
def _default_revision(self) -> MigrationScript:
command_args: Dict[str, Any] = self.command_args
op = ops.MigrationScript(
rev_id=command_args["rev_id"] or util.rev_id(),
message=command_args["message"],
upgrade_ops=ops.UpgradeOps([]),
downgrade_ops=ops.DowngradeOps([]),
head=command_args["head"],
splice=command_args["splice"],
branch_label=command_args["branch_label"],
version_path=command_args["version_path"],
depends_on=command_args["depends_on"],
)
return op
def generate_scripts(self) -> Iterator[Optional[Script]]:
for generated_revision in self.generated_revisions:
yield self._to_script(generated_revision)

Some files were not shown because too many files have changed in this diff Show More