Python Django web应用程序在Sqlite中的独占读取/更新

Python Django web应用程序在Sqlite中的独占读取/更新,python,django,sqlite,Python,Django,Sqlite,我有一个简单的Django web应用程序,它带有一个Sqlite DB,用于收集用户的电影评论,其中每部电影都应该有两名评论员观看并提供评论 为了动态地实现2个评论/电影要求,我必须确保我不会向超过2个登录用户呈现给定的电影。否则,我将得到超过2个评论的电影 因此,在发送任何电影进行评论之前,我需要检查它是否还没有发送给2位评论人。问题是:如果我将这些信息保存在数据库中,我可能会有两个以上的并发请求选择某部电影并将其发送以供审阅,因为它们都同时执行了读取/检索操作 希望我有像“选择更新”这样的

我有一个简单的Django web应用程序,它带有一个Sqlite DB,用于收集用户的电影评论,其中每部电影都应该有两名评论员观看并提供评论

为了动态地实现2个评论/电影要求,我必须确保我不会向超过2个登录用户呈现给定的电影。否则,我将得到超过2个评论的电影

因此,在发送任何电影进行评论之前,我需要检查它是否还没有发送给2位评论人。问题是:如果我将这些信息保存在数据库中,我可能会有两个以上的并发请求选择某部电影并将其发送以供审阅,因为它们都同时执行了读取/检索操作

希望我有像“选择更新”这样的东西,但不幸的是SQLite不支持

有人有什么想法吗?提前谢谢。

我想你可以用它来解决你的问题。这是一个例子

如果您试图让两个并发事务写入同一个sqlite数据库,则可能会抛出“OperationalError:database is locked”。您可能希望使用Django ORM(参见链接),但这里有一个黑客示例来演示这个想法

import sqlite3
# 2 connections, 2 cursors
con = sqlite3.connect('test.db', isolation_level=None)
con2 = sqlite3.connect('test.db', isolation_level=None)
cur = con.cursor()
cur2 = con2.cursor()

# create really simple table
try:
    cur.execute("CREATE TABLE MOVIES(id INTEGER PRIMARY KEY, r1 INTEGER, r2 INTEGER)")
    cur.execute("INSERT INTO MOVIES(id,r1, r2) VALUES (1,0,0)")
    cur.execute("INSERT INTO MOVIES(id,r1, r2) VALUES (2,0,0)")
except:
    pass

# awkward read/write split mid-transaction is purely for demonstration purposes..
def read(cursor):
    cursor.execute("BEGIN IMMEDIATE TRANSACTION")  # get write lock straight away
    data = cursor.execute("SELECT * FROM MOVIES WHERE r1 == 0 OR r2 == 0")
    return data.fetchall()

def write(cursor, movie_id, reviewer_column, new_reviewer_id):
    cursor.execute("UPDATE MOVIES SET %s=%d WHERE id == %d AND %s ==0" % (
        reviewer_column, new_reviewer_id, movie_id, reviewer_column))
    cursor.execute("COMMIT")

# works fine
data1 = read(cur) # [(1, 0, 0), (2, 0, 0)]
write(cur, data1[0][0], "r1", 123)

# now we have concurrent access..
data1 = read(cur) # [(1, 123, 0), (2, 0, 0)]
data2 = read(cur2) # throws OperationalError: database is locked.
# the second thread should probably wait a bit before retrying.

# in the mean time..
write(cur, data1[0][0], "r2", 456) #works

# now it's safe for the second thread to retry
data2 = read(cur2) # [(2, 0, 0)]
write(cur2, data2[0][0], "r1", 457) #works
上述数据之后:

# MOVIES
# id |  r1 |  r2
#  1 | 123 | 456
#  2 | 457 |   0
它将保护您不在数据库中放入胡言乱语,但立即写入锁是一种稍微粗糙的方法