也许我在这里遗漏了一些非常简单的东西,但是我有一个Flask网站,其中有一个供人们参加的测试。我的数据库有一个TestAttempt
表,其定义如下:
class TestAttempt(db.Model, UserMixin):
user_id = db.Column(db.Integer,db.ForeignKey(User.id, ondelete='CASCADE'), primary_key=True)
attempt_number = db.Column(db.Integer)
attempt_data = db.Column(db.String(1000))
timestamps = db.Column(db.String(1000))
score = db.Column(db.Integer)
begin_time = db.Column(db.String(20))
该站点是为进行前后测试而设置的,因此attempt_number
字段应为1
或2
。我有一个名为get_or_create_test_attempt()
的函数,它可以像锡罐上所说的那样工作。如果用户已经尝试打开,则返回它;否则,将创建一个新的。最初的定义如下:
def get_or_create_test_attempt(user_id, attempt_id):
attempt = TestAttempt.query.filter_by(user_id=user_id, attempt_number=attempt_id).first()
if attempt == None:
new_attempt = TestAttempt(user_id=user_id, attempt_number=attempt_id, begin_time=str(datetime.now().strftime("%m%d%Y%H%M%S")))
db.session.add(new_attempt)
db.session.commit()
return new_attempt
else:
return attempt
这是行不通的:它没有出现任何问题,但是每当我提供2
作为attempt_id
时,它都会一直返回第一个。我添加了一些打印语句以尝试确定发生了什么并讲一些故事:
def get_or_create_test_attempt(user_id, attempt_id):
print("Asked for:", user_id, attempt_id)
attempt = TestAttempt.query.filter_by(user_id=user_id, attempt_number=attempt_id).first()
if attempt == None:
new_attempt = TestAttempt(user_id=user_id, attempt_number=attempt_id, begin_time=str(datetime.now().strftime("%m%d%Y%H%M%S")))
print("Created:", new_attempt.user_id, new_attempt.attempt_number)
db.session.add(new_attempt)
db.session.commit()
print("After commit:", new_attempt.user_id, new_attempt.attempt_number)
return new_attempt
else:
return attempt
当我请求attempt_id
的{{1}}和2
的{{1}}时,得到以下输出:
user_id
注意:我还在函数调用后添加了“已接收”部分,如下所示:
1160
无奈之下,我试图对刚刚创建的对象运行一个新查询,但显示出相同的行为:
Asked for: 1160 2
Created: 1160 2
After commit: 1160 1
Recieved: 1160 1
输出令人困惑:
attempt = get_or_create_test_attempt(current_user.id, attempt_id)
print("Recieved:", attempt.user_id, attempt.attempt_number)
请注意,如果我首先开始进行后期测试,那么这就是“普遍”测试-如果我尝试使用def get_or_create_test_attempt(user_id, attempt_id):
print("Asked for:", user_id, attempt_id)
attempt = TestAttempt.query.filter_by(user_id=user_id, attempt_number=attempt_id).first()
if attempt == None:
new_attempt = TestAttempt(user_id=user_id, attempt_number=attempt_id, begin_time=str(datetime.now().strftime("%m%d%Y%H%M%S")))
print("Created:", new_attempt.user_id, new_attempt.attempt_number)
db.session.add(new_attempt)
db.session.commit()
print("After commit:", new_attempt.user_id, new_attempt.attempt_number)
new_attempt = TestAttempt.query.filter_by(user_id=user_id, attempt_number=attempt_id).first()
print("After new query:", new_attempt.user_id, new_attempt.attempt_number, "\tand query was fed:", user_id, attempt_id)
return new_attempt
else:
return attempt
的{{1}}访问/创建尝试,则它总是会给出一个其中Asked for: 1160 2
Created: 1160 2
After commit: 1160 1
After new query: 1160 1 and query was fed: 1160 2
Recieved: 1160 1
中的attempt_number
。还要注意,即使该函数未能返回corect对象,也会创建 ,因为我可以在数据库中以正确的参数看到它。
我不知道是什么原因导致了这种行为。欢迎任何输入。
答案 0 :(得分:1)
您的user_id
列是primary_key
,您在表中只能有1个用户条目,即您将无法使用相同的{{ 1}}。您可以尝试在user_id
和user_id
列中创建一个复合主键。