最近我在为 openEuler 社区添加一个 FAQ 模块, 这一系列正是我在这一过程中的总结
全部内容: 如何编写一个 Python Web 应用(零)
简单增删改查
参考:
复杂关系: 一对一, 一对多
在 Mybatis 中, 实现一对多和一堆一, 需要在 .xml 文件或 @Select
注解中生命映射, 但咱 SQLAlchemy 中, 只需要一个参数.
这是一个例子. 这里 EQuestion
和 EQuestionDescription
是一对多的关系.
/models.py
:
from faq import db
class EQuestion(db.Model):
__tablename__ = 'e_question'
id = db.Column(db.String(20), primary_key=True)
std_description = db.Column(db.String(250), unique=True)
class EQuestionDescription(db.Model):
__tablename__ = 'e_question_description'
id = db.Column(db.String(20), primary_key=True)
description = db.Column(db.String(200), nullable=False)
question_id = db.Column(db.ForeignKey('e_question.id'), index=True)
question = db.relationship('EQuestion', backref='e_question_descriptions', primaryjoin='EQuestionDescription.question_id == EQuestion.id')
只需要在 "一对多" 中 "多" 的一方加入:
question = db.relationship('EQuestion', backref='e_question_descriptions', primaryjoin='EQuestionDescription.question_id == EQuestion.id')
接下来, 编写一个 CLI COmmand 来测试一下:
@app.cli.command('hello')
def hello():
question: EQuestion = EQuestion.query.get('2')
print(question)
descriptions = question.e_question_descriptions
print(descriptions)
description: EQuestionDescription = descriptions[0]
print(description)
question: EQuestion = description.question
print(question)
结果:
PS D:\my\flask\app> flask hello
<EQuestion 2>
[<EQuestionDescription 3>, <EQuestionDescription 9>]
<EQuestionDescription 3>
<EQuestion 2>
使用 sqlacodegen 实现针对 SQLAlchemy 的逆向工程
这里只是介绍这个有力的工具:
参考: flask 插件 flask-sqlacodegen
需要注意的是, 由 flask-sqlacodegen 直接生成的代码并不能直接适应我们原有的代码
下面是在 PowerShell 中完整的生成命令. 他将在当前目录中生成一个 models.py
文件
PS D:\my\flask\app> (.\venv\Scripts\Activate.ps1) ;((flask-sqlacodegen mysql://root:123456@localhost:3306/openeuler_faq --flask) -replace 'db = SQLAlchemy\(\)','from faq import db' -replace 'from flask_sqlalchemy import SQLAlchemy','' | out-file faq/models.py -encoding utf8)
关于这一命令的含义, 我将在最后一节详谈
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。