Atitti 固化数据库表结构方案

本文介绍了一种固化数据库表结构的方法,旨在通过通用化的表结构提高项目开发效率。重点讲解了如何通过抽象动词和名词来定义表结构,并讨论了特殊情况下独立建表的策略。

Atitti 固化数据库表结

Atitti 固化数据库表结构方案

1. 固化数据库表结的重要意义 1

2. 如何固化表结构 1

2.1. 向上抽象一层,以动词有目标,以名词为存储对象。 1

2.2. 数据类型datatype字段:这个用来表明数据是属于哪个功能的。方便筛选 1

3. 特例20%::对于十分频繁的功能,也可以特殊化单独建表 2

 

1. 固化数据库表结的重要意义

一个项目,基本由三部分组成,界面 ui ,业务逻辑,数据库

 

 固化数据库表,基本就可以达到了立即提升很大效率的程度。。。

 

 

2. 如何固化表结构

2.1. 向上抽象一层,以动词有目标,以名词为存储对象。

比如收藏xxxx功能。。  就可以建立一个收藏表fav,包含收藏对象id和收藏标题即可。。

 

这样比较通用化,未来可以凡是收藏aaa,bbb,cccd功能的都是可以用到的模块。

 

2.2. 数据类型datatype字段:这个用来表明数据是属于哪个功能的。方便筛选

 

 

 

3. 特例20%::对于十分频繁的功能,也可以特殊化单独建表

 

 

 

 

作者:: 绰号:老哇的爪子claw of Eagle 偶像破坏者Iconoclast image-smasher

捕鸟王"Bird Catcher  kok  虔诚者Pious 宗教信仰捍卫者 Defender Of the Faith. 卡拉卡拉红斗篷 Caracalla red cloak 万兽之王

简称:: Emir Attilax Akbar 埃米尔 阿提拉克斯 阿克巴

全名::Emir Attilax Akbar bin Mahmud bin  attila bin Solomon bin adam Al Rapanui 埃米尔 阿提拉克斯 阿克巴 本 马哈茂德 本 阿提拉 本 所罗门 本亚当  阿尔 拉帕努伊

常用名:艾提拉(艾龙),  EMAIL:1466519819@qq.com

 

 

头衔:uke总部o2o负责人,全球网格化项目创始人,

uke交友协会会长  uke捕猎协会会长 Emir Uke部落首席大酋长,

 

uke宗教与文化融合事务部部长, uke宗教改革委员会副主席

uke制度与重大会议委员会委员长,uke保安部首席大队长,uke制度检查委员会副会长,

 

uke 首席cto   软件部门总监 技术部副总监  研发部门总监主管  产品部副经理 项目部副经理   uke科技研究院院长 uke软件培训大师

 

uke波利尼西亚区大区连锁负责人 汤加王国区域负责人 uke克尔格伦群岛区连锁负责人,莱恩群岛区连锁负责人,uke布维岛和南乔治亚和南桑威奇群岛大区连锁负责人

 Uke软件标准化协会理事长理事长 Uke 数据库与存储标准化协会副会长

 

uke终身教育学校副校长   Uke医院 与医学院方面的创始人

 uec学院校长, uecip图像处理机器视觉专业系主任   uke文档检索专业系主任

Uke图像处理与机器视觉学院首席院长

Uke 户外运动协会理事长  度假村首席大村长   uke出版社编辑总编

 

转载请注明来源:attilax的专栏  ?http://blog.youkuaiyun.com/attilax

--Atiend  v8

 

 

<think>我们使用Flask-SQLAlchemy时,可以通过已有的数据库表结构反向生成模型类(Model Classes)。这通常称为“反射”(reflection)或“自动生成模型”。 但注意:Flask-SQLAlchemy本身没有直接提供从数据库表生成模型类的命令,但我们可以使用SQLAlchemy的自动映射功能,或者使用第三方工具如`sqlacodegen`。 这里提供两种方法: 方法一:使用SQLAlchemy的自动映射(Automap) 这种方法适用于已有数据库,我们通过反射表结构来创建模型。 方法二:使用sqlacodegen工具(推荐) `sqlacodegen`是一个第三方库,它可以从现有数据库生成SQLAlchemy模型代码。 下面分别介绍这两种方法。 方法一:使用SQLAlchemy的自动映射(在Flask中集成) 步骤: 1. 创建一个Flask应用和SQLAlchemy实例。 2. 使用SQLAlchemy的自动映射功能。 示例代码: 注意:这种方法生成的模型类不是直接继承自`db.Model`(Flask-SQLAlchemy的基类),而是继承自SQLAlchemy的基类。因此,在Flask中可能需要调整。 方法二:使用sqlacodegen 安装sqlacodegen: ```bash pip install sqlacodegen ``` 然后,使用命令行生成模型代码。例如: ```bash sqlacodegen --outfile models.py mysql+pymysql://username:password@localhost/dbname ``` 但是,在Flask项目中,我们通常希望模型类继承自`db.Model`(即Flask-SQLAlchemy的基类)。为此,我们可以使用`--flask`选项: ```bash sqlacodegen --flask --outfile models.py mysql+pymysql://username:password@localhost/dbname ``` 这样生成的模型类就会使用`db.Model`作为基类。 然而,有时我们可能需要在代码中动态生成模型(而不是生成静态文件),或者需要集成到Flask应用中。这时,我们可以使用方法一,或者使用`sqlacodegen`的库形式(但sqlacodegen主要设计为命令行工具)。 下面提供一个在Flask应用中使用自动映射(方法一)的示例代码: 注意:自动映射不会生成关系(如外键关系),它只会生成基本的列。如果需要关系,可能需要手动添加。 示例(自动映射): ```python from flask import Flask from flask_sqlalchemy import SQLAlchemy from sqlalchemy.ext.automap import automap_base app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'your_database_uri' db = SQLAlchemy(app) # 使用automap Base = automap_base() # 反射数据库表 Base.prepare(db.engine, reflect=True) # 获取映射后的类 User = Base.classes.user # 假设数据库中有一个名为'user'的表 # 现在你可以使用User类来查询 @app.route('/') def index(): users = db.session.query(User).all() # ... 处理 return "Hello" if __name__ == '__main__': app.run() ``` 但是,上述方法中,我们得到的User类并不是继承自`db.Model`,而是继承自`Base`(它是`declarative_base`的一个实例)。在Flask-SQLAlchemy中,我们通常希望使用`db.Model`。因此,另一种做法是使用`db.Model`作为基类,然后反射表结构到该基类上。 实际上,Flask-SQLAlchemy的`db`对象有一个`Model`类,我们可以通过以下方式反射表: ```python class User(db.Model): __tablename__ = 'user' __table_args__ = {'autoload': True, 'autoload_with': db.engine} # 这样,User类就通过反射加载了表结构 ``` 我们可以为每个表写一个这样的类。但是,如果表很多,我们可以动态创建这些类。例如: ```python from sqlalchemy import MetaData metadata = MetaData() metadata.reflect(bind=db.engine) tables = metadata.tables for table_name in tables: # 动态创建类 cls = type(table_name, (db.Model,), { '__table__': tables[table_name], '__mapper_args__': { 'primary_key': list(tables[table_name].primary_key.columns) } }) # 将类添加到全局变量中,以便使用 globals()[table_name] = cls ``` 但是,动态创建类可能不利于IDE的智能提示,而且关系(外键)可能不会自动处理。 因此,对于生产环境,推荐使用`sqlacodegen`生成模型文件,然后手动调整关系部分。 总结: 1. 如果只是需要快速反射表结构进行查询,可以使用自动映射(automap)或者使用`__table_args__`设置`autoload`。 2. 如果需要完整的模型类(包括在Flask中直接使用),推荐使用`sqlacodegen`生成模型文件,然后手动调整。 下面给出一个使用`autoload`的示例(针对单个表): ```python class User(db.Model): __tablename__ = 'user' __table_args__ = {'autoload': True, 'autoload_with': db.engine} ``` 这样,User类就会反射数据库中的'user'表的所有列。 注意:这种方法不会反射关系(比如外键关联的其他表的关系属性),需要自己手动添加。 因此,对于复杂的数据库结构,建议使用`sqlacodegen`生成基础模型,然后手动添加关系。 最后,提供一个使用`sqlacodegen`生成Flask-SQLAlchemy模型类的命令行示例: ```bash sqlacodegen --flask --outfile models.py mysql+pymysql://user:password@localhost/mydatabase ``` 然后,在Flask应用中导入这个models.py即可。 如果数据库连接信息在Flask配置中,也可以先设置环境变量,然后使用相同的连接字符串。 由于`sqlacodegen`是一个独立的工具,这里不展示其生成的代码,但你可以查看生成的models.py文件。 希望这些方法能帮助你反向生成模型类。 §§相关问题§§: 1. 如何在使用`autoload`反射表结构时,只反射特定的列? 2. 使用`sqlacodegen`生成模型时,如何排除某些表? 3. 在Flask-SQLAlchemy中,如何动态创建模型类(即运行时根据表名动态生成模型)? 4. 反射生成的模型类,如何添加自定义方法?</think>### 反向生成 SQLAlchemy 模型类的方法 根据数据库表结构反向生成 SQLAlchemy 模型类主要有两种方法:使用 `sqlacodegen` 工具或 SQLAlchemy 的反射功能。以下是详细解决方案: --- ### 方法一:使用 sqlacodegen 工具(推荐) **安装:** ```bash pip install sqlacodegen ``` **使用命令:** ```bash # 基础命令 sqlacodegen postgresql://user:password@localhost/dbname --outfile models.py # 生成 Flask-SQLAlchemy 模型(添加 --flask 参数) sqlacodegen mysql+pymysql://user:password@localhost/dbname --flask --outfile models.py # 排除特定表(如排除临时表 temp_*) sqlacodegen sqlite:///database.db --flask --tables users,products --outfile models.py ``` **生成示例(models.py):** ```python from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() 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) created_at = db.Column(db.DateTime, server_default=db.func.now()) orders = db.relationship('Order', backref='user', lazy=True) class Order(db.Model): __tablename__ = 'orders' id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) amount = db.Column(db.Float) ``` --- ### 方法二:使用 SQLAlchemy 反射(动态生成) 在代码中动态反射表结构: ```python from flask import Flask from flask_sqlalchemy import SQLAlchemy from sqlalchemy import inspect app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db' db = SQLAlchemy(app) # 动态反射模型类 def reflect_models(): inspector = inspect(db.engine) for table_name in inspector.get_table_names(): # 创建动态模型类 cls = type( table_name.capitalize(), # 类名(如 Users) (db.Model,), { '__tablename__': table_name, '__table_args__': {'autoload': True, 'autoload_with': db.engine} } ) globals()[cls.__name__] = cls # 添加到全局命名空间 reflect_models() # 使用示例 if __name__ == '__main__': users = globals()['Users'].query.all() # 访问 Users 模型 print([u.name for u in users]) ``` **关键点说明:** 1. `inspect(db.engine)`:获取数据库元数据 2. `autoload=True`:自动加载表结构 3. 动态创建类:使用 `type()` 动态生成继承自 `db.Model` 的类 4. 外键关系需手动添加(反射不会自动生成 relationships) --- ### 手动添加关系的示例 如果表有外键关联,需手动补充 `db.relationship`: ```python class Order(db.Model): __tablename__ = 'orders' __table_args__ = {'autoload': True} # 手动添加关系(假设存在 user_id 外键) user = db.relationship('User', backref=db.backref('orders', lazy=True)) ``` --- ### 两种方法对比 | **特性** | **sqlacodegen** | **反射 (autoload)** | |------------------------|-------------------------------------|----------------------------------| | 输出结果 | 生成静态 Python 文件 | 运行时动态生成模型 | | 关系 (relationships) | 自动生成外键关系 | 需手动添加 | | 自定义修改 | 可直接编辑生成的代码 | 需在动态生成后修改类 | | 适用场景 | 项目初始化/模型固化 | 动态数据库结构/临时查询 | --- ### 注意事项 1. **复杂关系**:多对多、复合主键等复杂结构可能需要手动调整 2. **列覆盖**:可覆盖自动生成的列定义(如添加自定义验证): ```python class User(db.Model): __tablename__ = 'users' __table_args__ = {'autoload': True} # 覆盖 email 列定义 email = db.Column(db.String(120), nullable=False, unique=True) ``` 3. **视图支持**:使用 `--views` 参数可反射数据库视图(sqlacodegen)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值