F

Flask 搭建网站记录

轻松学习 技术 2024-08-17

Flask 搭建网站记录

建站目的

主要目的是用于维护资料的方便性。可以加一些验证减少人员的错误。

  1. 自动生成新的id,而不是靠人去自己找,杜绝重复
  2. 资料放在db,不会存在太多版本,资料是一致的
  3. 有上传和下载excel的功能,方便批量生成ID
  4. 有query功能,可以针对特定的资料进行编辑

文件目录

-app
    - templates
        - login.html
        - index.html
        - base.html
        - upload.html
        - query.html
    - run.py
    - query.py
    - upload.py
    - db.py
    - auth.py

使用的功能

Blueprint

由于有好几个功能,最初的设计是全部放到一个主文件里面去。但是由于后面功能的增加,感觉不是太便捷。所以修改为使用蓝图进行配置。

    import upload
    import auth
    import query

    app.register_blueprint(upload.bp)
    app.register_blueprint(auth.bp)
    app.register_blueprint(query.bp)

    auth.py 配置
    bp = Blueprint('auth', __name__)

配置的时候比较简单,需要注意的是使用的时候要修改一些URL的引用。比如我auth.py 里面有个login 方法。如果未登录时,都要跳转回这里,需要使用redirect(url_for('auth.login'))

在每个文件里面可以是用同样的变量名bp,这样比较方便在主函数的调用注册。

db的使用

最初用的Pymysql 可以做SQL的简单增删改查。但是处理文件时,我使用了pandas库,而pandas默认只能支持sqlalchemy。所以在切分文件时,改成了全部使用sqlalchemy.

DB的初始化是参考官网的一个sample去初始化的。这里的调试遇到的最大问题。就是如果在主函数初始化,在其他文件去调用DB时,会报循环引用错误。就是app.py import upload.py, 而upload.py又引用的app.py里面的一个函数或者变量。最终导致一直报错。这种情形如果都写一个文件里面,不会出现。

解决方式是,在主函数里面,初始化DB db.init_db(app)。原始范例里面init_db_command 是一个命令行命令,当它被执行时,Flask 会自动创建并推送应用上下文,因此在这个命令中调用 init_db 不会有上下文问题。而如果要直接使用init_db函数只是注册了命令,实际的数据库初始化是在命令行调用时执行的。


from flask import g
from sqlalchemy import create_engine

def get_db():
    """Connect to the application's configured database. The connection
    is unique for each request and will be reused if this is called
    again.
    """
    if "db" not in g:
        g.db = create_engine("mysql+pymysql://root:mysql@localhost/powerbi")
    return g.db

def close_db(e=None):
    """If this request connected to the database, close the
    connection.
    """
    db = g.pop("db", None)
    if db is not None:
        db.close()

def init_db(app):
    """Clear existing data and create new tables."""
    with app.app_context()
        db = get_db()

    # with current_app.open_resource("schema.sql") as f:
    #     db.executescript(f.read().decode("utf8"))

当我们在其他文件需要引用数据库时,直接import这个db文件的get_db方法即可。返回的是一个SQLAlchemy的engine

from db import get_db
db=get_db()

其他文件的逻辑实现

这里实现就比较简单的,大多是数据的增删改查。附上几个简单的用法。

  • 搭配pandas使用

    # 使用pandas查询资料获取结果
    query = "SELECT * FROM dpn_status WHERE Substitute = %(substitute_id)s"
    params = {'substitute_id': id}
    results = pd.read_sql_query(query, con=db_engine, params=params)
    print(results)
  • 直接执行sql,需要注意SQL语句要搭配text()函数,不然无法执行
with db.connect() as conn:
  query = text(
  '''SELECT * FROM dpn_status WHERE Substitute = :sub LIMIT 1'''
  )
  result = conn.execute(query, {
  'sub': substitutes[0]
  }).fetchone()
  print(result)
  conn.execute(
  text(
  '''INSERT INTO dpn_status (DPN, 71PN,Substitute,Model,Region,Series,MP,EOP,EOW,WarrantyPeriod) VALUES (:DPN,:71PN,:Substitute,:Model,:Region,:Series,:MP,:EOP,:EOW,:WarrantyPeriod)'''
  ), {
  "DPN": dpns[i],
  "71PN": pn71s[i],
  "Substitute": substitutes[i],
  "Model": result[4],
  "Region": regions[i],
  "Series": result[6],
  "MP": result[7],
  "EOP": result[8],
  "EOW": result[9],
  "WarrantyPeriod": result[10]
  })
  conn.commit()
  • 删除资料,参数的搭配使用
query = text("DELETE FROM dpn_status where id = :id")
result = db_engine.connect().execute(query, {'id': id})

不足和思考

整体实现这个功能大约用了两周的时间。对于框架的使用还是不够熟悉,特别是数据库的初始化部分。现在回想一下,整个思路清晰多了。当然这里还有一些不足,比如我的登录验证是使用的明文密码存储来验证。文件的版本管控没有搭配git。

PREV
再读calculate
NEXT
PowerBI使用SVG绘制图表

评论(0)

发布评论