我有这个原始的sql代码,我需要在Flask中将其重写为SQlalchemy查询:
@app.route('/view/<date>')
def view(date):
db = get_db()
cur = execute('select entry_date from log_date where entry_date = ?', [date])
result = cur.fetchone()
d = datetime.strptime(str(result['entry_date']),'%Y%m%d')
pretty_date = datetime.strftime(d, '%B %d, &Y)
return render_template('day.htm;',date=pretty_date)
我尝试这样做:
@app.route('/view/<entry_date>',methods=['GET','POST'])
def view(entry_date):
dates = Log_date.query.filter_by(entry_date=entry_date).first()
selected_date = datetime.strptime(dates, "%Y%m%d").date()
"""foods = Food.query.with_entities(Food.id,Food.name).all()"""
return render_template('day.html',selected_date=selected_date)
但仍找不到页面。
请注意,我的模型中entry_date
是DateTime:
class Log_date(db.Model):
id = db.Column(db.Integer, primary_key=True)
entry_date = db.Column(db.DateTime,nullable=False)
此外,我尝试使用DateTime Converter进行如下转换:
from datetime import datetime
from werkzeug.routing import BaseConverter, ValidationError
class DateConverter(BaseConverter):
"""Extracts a ISO8601 date from the path and validates it."""
regex = r'\d{4}-\d{2}-\d{2}'
def to_python(self, value):
try:
return datetime.strptime(value, '%Y-%m-%d').date()
except ValueError:
raise ValidationError()
def to_url(self, value):
return value.strftime('%Y-%m-%d')
app.url_map.converters['date'] = DateConverter
但仍然没有结果。
下面是一个简单的单个文件示例。检查浏览器结果是否满足以下要求:
找不到该URL,404响应
http://127.0.0.1:5000/view
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
有效的ISO日期,但不在数据库中
http://127.0.0.1:5000/view/2019-12-31
Date:2019-12-31 not found
有效的ISO日期和数据库中的日期
http://127.0.0.1:5000/view/2020-01-01
Date:2020-01-01 found
无效的ISO日期,无第13个月,404响应
http://127.0.0.1:5000/view/2020-13-01
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
这是代码,注释使用flask-sqlalchemy。
from flask import Flask
from datetime import datetime, date
from werkzeug.routing import BaseConverter, ValidationError
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class LogDate(db.Model):
id = db.Column(db.Integer, primary_key=True)
entry_date = db.Column(db.Date(), nullable=False)
def __str__(self):
return f'ID: {self.id}; Entry Date: {self.entry_date}'
class ISODateConverter(BaseConverter):
"""Extracts a ISO8601 date from the path and validates it."""
regex = r'\d{4}-\d{2}-\d{2}'
def to_python(self, value):
try:
# try and convert a string to a datetime object and then get a date object
return datetime.strptime(value, '%Y-%m-%d').date()
except ValueError:
raise ValidationError()
def to_url(self, value):
if isinstance(value, date):
return value.strftime('%Y-%m-%d')
app = Flask(__name__)
app.url_map.converters['iso_date'] = ISODateConverter
app.config['SECRET_KEY'] = '123456790'
# Create in-memory database
app.config['DATABASE_FILE'] = 'sample_db.sqlite'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + app.config['DATABASE_FILE']
app.config['SQLALCHEMY_ECHO'] = True
db.init_app(app)
@app.route('/view/<iso_date:input_date>')
def view(input_date):
print(type(input_date))
# first() returns a single object or None
_log_date = LogDate.query.filter(LogDate.entry_date == input_date).first()
# or using filter_by
# _log_date = LogDate.query.filter_by(entry_date=input_date).first()
if not _log_date:
return f'Date:{input_date} not found'
return f'Date:{input_date} found !!!'
@app.before_first_request
def build_sample_db():
db.drop_all()
db.create_all()
# add three dates
db.session.add_all([LogDate(entry_date=d) for d in [date(2020, 1, 1), date(2020, 2, 1), date(2020, 3, 1)]])
db.session.commit()
if __name__ == '__main__':
app.run()