使用SQL Alchemy提交对象后更改对象

时间:2020-11-09 21:30:55

标签: python flask sqlalchemy flask-sqlalchemy

也许我在这里遗漏了一些非常简单的东西,但是我有一个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字段应为12。我有一个名为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对象,也会创建 ,因为我可以在数据库中以正确的参数看到它。

我不知道是什么原因导致了这种行为。欢迎任何输入。

1 个答案:

答案 0 :(得分:1)

您的user_id列是primary_key,您在表中只能有1个用户条目,即您将无法使用相同的{{ 1}}。您可以尝试在user_iduser_id列中创建一个复合主键。

相关问题