I have this model Problem
with a DateTime object: the current date. I want to add 3 more attributes, "reviewDate1," "reviewDate2," and "reviewDate3." I want them to be spaced out at 1 day after today, 3 days after, and 7 days after.
models.py:
from datetime import timedelta
from flask_sqlalchemy import SQLAlchemy
from uuid import uuid4
from sqlalchemy import DateTime, func, text
db = SQLAlchemy()
def get_uuid():
return uuid4().hex
class Problem(db.Model):
id = db.Column(db.String, primary_key=True, unique=True, default=get_uuid)
problemName = db.Column(db.String(200), nullable=False, unique=True)
url = db.Column(db.String, nullable=False)
date = db.Column(db.DateTime, default=func.current_date())
reviewDate1 = db.Column(db.DateTime, default=func.current_date() + timedelta(days=1))
def to_json(self):
return {
"id": self.id,
"problemName": self.problemName,
"url": self.url,
"date": self.date,
"reviewDate1": self.reviewDate1
}
app.py:
@app.route("/create", methods=["POST"])
def create():
problemName = request.json["problemName"]
url = request.json["url"]
# Check if problem already exists
problem_exists = Problem.query.filter_by(problemName=problemName).first() is not None
if problem_exists:
return jsonify({"error": "Problem already exists."}), 409
# Add new problem
new_problem = Problem(problemName=problemName, url=url)
db.session.add(new_problem)
db.session.commit()
return jsonify({
"problemName": problemName,
"url": url,
"date": new_problem.date,
"review1": new_problem.reviewDate1
}), 201
I tried using timedelta
but for some reason I get an error "TypeError: fromisoformat: argument must be str" when I try to create a problem:
{ "problemName": "a", "url": "a" }
.
I am fairly new to Flask-SQLAlchemy so can someone explain what I am doing wrong and if there is any other way I can go about this?
default=func.current_date() + timedelta(days=1)
is mixing a server-side function (func.current_date()
) with a client-side timedelta()
, and the database is getting confused. engine.echo = True
shows that the statement is
INSERT INTO problem (id, "problemName", url, date, "reviewDate1")
VALUES (?, ?, ?, CURRENT_DATE, (CURRENT_DATE + ?)) RETURNING date, "reviewDate1"
and the parameter values are
('f14790ef25004685b3b20199147dfe79', 'a', 'a', '1970-01-02 00:00:00.000000')
Your default should either be all server-side or all client-side. I would suggest using the following (client-side) for consistency:
class Problem(db.Model):
id = db.Column(
db.String, primary_key=True, unique=True, default=lambda: uuid4().hex
) # no separate get_uuid() function required
problemName = db.Column(db.String(200), nullable=False, unique=True)
url = db.Column(db.String, nullable=False)
date = db.Column(
db.DateTime, default=datetime.now().date
) # note .date not .date()
reviewDate1 = db.Column(
db.DateTime, default=lambda: datetime.now().date() + timedelta(days=1)
)
which generates
INSERT INTO problem (id, "problemName", url, date, "reviewDate1") VALUES (?, ?, ?, ?, ?)
[generated in 0.00127s] ('e17a781a468f4aa7b0bfea02dbe93d4d', 'a', 'a', '2024-06-16 00:00:00.000000', '2024-06-17 00:00:00.000000')