【问题标题】:SQLAlchemy unproper data updatingSQLAlchemy 数据更新不当
【发布时间】:2017-06-15 09:31:13
【问题描述】:

我正在 Flask + SQLALchemy + sqllite 上编写一个简单的 Web 应用程序

我有这样的课:

class Document(db.Model):
    # Sha will be primary key for every document
    hex_sha = db.Column(db.String(64), unique=True, primary_key = True)
    # How many times this document was uploaded
    count = db.Column(db.Integer)
    def __init__(self, hex_sha):
        self.hex_sha = hex_sha
        self.count = 1

从客户端,你可以上传一些txt文件,服务器必须返回,这个SHA256 hash值的文件被上传了多少次。

首先我将文件转换为 utf-8 表示,然后使用 hashlib 库从中找到 SHA256:

from hashlib import sha256
file_hex_sha = sha256()
file_hex_sha.update(file)
file_hex_sha = file_hex_sha.hexdigest()

然后我检查,如果这样的 SHA256 哈希已经存储在我的数据库中。如果是,我将计数器加一,否则我用这样的 SHA256 哈希创建新记录:

# Try to find such document in db
db_file = Document.query.filter_by(hex_sha=file_hex_sha).first()
# If there is no such document in database
if db_file is None:
    new_db_file = Document(file_hex_sha)
    db.session.add(new_db_file)
    response = str(new_db_file.count)
    db.session.commit()
    return response
# If we found same document
else:
    db_file.count += 1
    response = str(db_file.count)
    db.session.commit()
    return response

当我在 localhost 上测试此代码时,它可以正常工作。

但是当我在 Google App Engine 上部署这个应用程序时,我遇到了这样的问题:

当我多次上传同一个文件时,计数器返回类似这样的内容

Amount is:
1
2
3
4
1 <-----
2 <-----
5
3
...

看来,SQLAlchemy 创建了新记录,尽管这样的记录已经存在(并且 sha 键是 primary 和 unqique

我会在哪里犯错?

【问题讨论】:

  • 我会删除 self.count = 1 并将列声明更改为 count = db.Column(db.Integer, default=1) 只是为了检查。附:其实我一点也不喜欢那个init,我觉得这可能是个问题。如果我是你,我会重写模型以利用 'default' kwarg 并删除 init
  • 我试过你说的技巧,但是没有用

标签: python sqlite google-app-engine flask flask-sqlalchemy


【解决方案1】:

我认为这是因为请求正在并行处理。这会导致竞态条件,因此计数会被覆盖。

以下MySql构造的解决方案:SELECT &lt;Query&gt; FOR UPDATE

这会执行行锁定

这可以通过with_for_update在sqlalchemy中实现

您可以在此处阅读更多信息:http://docs.sqlalchemy.org/en/latest/core/selectable.html#sqlalchemy.sql.expression.Select.with_for_update

【讨论】:

    猜你喜欢
    • 2015-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 2017-11-25
    • 1970-01-01
    • 2010-09-21
    相关资源
    最近更新 更多