스레드에서 생성된 개체는 동일한 스레드에서만 사용할 수 있습니다.
문제를 찾을 수 없습니다.
@app.route('/register', methods=['GET', 'POST'])
def register():
form = RegisterForm(request.form)
if request.method=='POST' and form.validate():
name = form.name.data
email = form.email.data
username = form.username.data
password = sha256_crypt.encrypt(str(form.password.data))
c.execute("INSERT INTO users(name,email,username,password)
VALUES(?,?,?,?)", (name, email, username, password))
conn.commit
conn.close()
오류:
파일 "C:\Users\app.py ", 59번 행, 레지스터 c.사용자에게 삽입(이름, 이메일, 사용자 이름, 암호) 값(?, ??), (이름, 이메일, 사용자 이름, 암호) 프로그래밍 오류: 스레드에서 생성된 SQLite 개체는 동일한 스레드에서만 사용할 수 있습니다.개체가 스레드 ID 23508에서 생성되었으며 스레드 ID 22640입니다.
HTML 파일에서 이름, 이메일 사용자 이름, 비밀번호를 사용할 수 없다는 뜻입니까?어떻게 해결해야 합니까?
데이터베이스에 연결할 때 다음을 추가합니다.
conn = sqlite3.connect('your.db', check_same_thread=False)
커서 'c'가 동일한 스레드에서 생성되지 않았습니다. 플라스크 앱을 실행할 때 초기화되었을 수 있습니다.
다음과 같은 동일한 방법으로 SQLite 개체(연결부 및 커서)를 생성할 수 있습니다.
@app.route('/')
def dostuff():
with sql.connect("database.db") as con:
name = "bob"
cur = con.cursor()
cur.execute("INSERT INTO students (name) VALUES (?)",(name))
con.commit()
msg = "Done"
engine = create_engine(
'sqlite:///restaurantmenu.db',
connect_args={'check_same_thread': False}
)
나를 위해 일함
다음을 시도해 볼 수 있습니다.
engine=create_engine('sqlite:///data.db', echo=True, connect_args={"check_same_thread": False})
그것은 나에게 효과가 있었다.
저의 경우, 두 개의 파이썬 파일이 sqlite 엔진을 생성하여 다른 스레드에서 작동하는 것과 같은 문제가 있습니다.여기서 SQLLchemy 문서를 읽어보면 두 파일 모두 싱글톤 기법을 사용하는 것이 더 나을 것 같습니다.
# maintain the same connection per thread
from sqlalchemy.pool import SingletonThreadPool
engine = create_engine('sqlite:///mydb.db',
poolclass=SingletonThreadPool)
모든 경우를 해결할 수는 없지만, 가끔 같은 오류가 발생하지만 쉽게 극복할 수 있어 브라우저 페이지가 새로워집니다.코드 디버그를 할 때만 사용하기 때문에 저는 괜찮습니다.보다 영구적인 솔루션을 위해서는 Postgre와 같은 다른 데이터베이스를 선택해야 합니다.SQL 또는 기타 데이터베이스
https://docs.python.org/3/library/sqlite3.html 에서 언급하고 @Snidhi Sofpro가 댓글로 지적한 바와 같이
기본적으로 check_same_thread는 True이고 생성 스레드만 연결을 사용할 수 있습니다.False를 설정하면 반환된 연결이 여러 스레드에서 공유될 수 있습니다.연결이 동일한 여러 스레드를 사용하는 경우 데이터 손상을 방지하기 위해 쓰기 작업을 사용자가 직렬화해야 합니다.
직렬화를 달성하는 한 가지 방법:
import threading
import sqlite3
import queue
import traceback
import time
import random
work_queue = queue.Queue()
def sqlite_worker():
con = sqlite3.connect(':memory:', check_same_thread=False)
cur = con.cursor()
cur.execute('''
CREATE TABLE IF NOT EXISTS test (
id INTEGER PRIMARY KEY AUTOINCREMENT,
text TEXT,
source INTEGER,
seq INTEGER
)
''')
while True:
try:
(sql, params), result_queue = work_queue.get()
res = cur.execute(sql, params)
con.commit()
result_queue.put(res)
except Exception as e:
traceback.print_exc()
threading.Thread(target=sqlite_worker, daemon=True).start()
def execute_in_worker(sql, params):
# you might not really need the results if you only use this
# for writing unless you use something like https://www.sqlite.org/lang_returning.html
result_queue = queue.Queue()
work_queue.put(((sql, params), result_queue))
return result_queue.get(timeout=5)
def insert_test_data(seq):
time.sleep(random.randint(0, 100) / 100)
execute_in_worker(
'INSERT INTO test (text, source, seq) VALUES (?, ?, ?)',
['foo', threading.get_ident(), seq]
)
threads = []
for i in range(10):
thread = threading.Thread(target=insert_test_data, args=(i,))
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
for res in execute_in_worker('SELECT * FROM test', []):
print(res)
# (1, 'foo', 139949462500928, 9)
# (2, 'foo', 139949496071744, 5)
# (3, 'foo', 139949479286336, 7)
# (4, 'foo', 139949487679040, 6)
# (5, 'foo', 139949854099008, 3)
# (6, 'foo', 139949470893632, 8)
# (7, 'foo', 139949862491712, 2)
# (8, 'foo', 139949845706304, 4)
# (9, 'foo', 139949879277120, 0)
# (10, 'foo', 139949870884416, 1)
되어 있지만 에 .while
리
- https://docs.python.org/3/library/queue.html
- https://docs.python.org/3/library/threading.html#threading.Thread.join
- https://docs.python.org/3/library/threading.html#threading.get_ident
저도 같은 문제가 있어서 매번 전화를 걸 때마다 연결을 닫아 고쳤습니다.
results = session.query(something, something).all()
session.close()
는 에 .execute()
데, 즉 SQLite DB 입니다입니다.
나는 당신이 다음을 가지고 있다고 생각합니다.
conn = sqlite3.connect('your_database.db')
c = conn.cursor()
플라스크 스크립트의 맨 위 어딘가에 있습니다. 스크립트를 처음 실행할 때 초기화됩니다.
때.register
함수가 호출되고, 초기 스크립트 실행과는 다른 새로운 스레드가 프로세스를 처리합니다.따라서 이 새로운 스레드에서는 SQLite가 오류로 캡처하는 다른 스레드의 개체 인스턴스를 사용하게 됩니다. 앱 실행 중에 다른 스레드에 의해 DB에 액세스할 것으로 예상되는 경우 데이터가 손상될 수 있기 때문입니다.
따라서 다른 방법으로, 동일 스레드 확인 SQLite 기능을 비활성화하는 대신 호출 중인 HTTP Method 내에서 DB 연결 및 커서 초기화를 시도할 수 있습니다.
이렇게 하면 실행 시 SQLite 개체 및 활용률이 동일한 스레드에 있게 됩니다.
코드는 중복되지만 데이터가 비동기적으로 액세스되는 상황에서 사용자를 보호하고 데이터 손상을 방지할 수 있습니다.
이것들이 사실입니까?
-
app
인에@app.route
플라스크 앱입니다. - 로컬 개발 서버를 실행하는 동안 이 오류가 발생합니다.
- 합니다.
app.run()
그렇다면 문제는 Flask 개발 서버가 기본적으로 멀티 스레드라는 것입니다.이 문제는 전화를 통해 해결할 수 있습니다.run
와 함께threaded=False
:
app.run(threaded=False)
저는 이 문제를 겪고 있었고 이 게시물에 답을 사용하고 있습니다.여기에 다시 게시할 내용:
creator = lambda: sqlite3.connect('file::memory:?cache=shared', uri=True)
engine = sqlalchemy.create_engine('sqlite://', creator=creator)
engine.connect()
따라서 이 문자열 "file::memory:? cache=shared"를 sqalchemy에 URL로 지정할 수 없다는 문제를 우회합니다.저는 많은 답변을 보았지만 이를 통해 여러 스레드 간에 공유되는 메모리 데이터베이스에서 SQLite를 사용할 때의 모든 문제가 해결되었습니다.속도를 위해 두 개의 스레드로 두 개의 테이블을 만들어 데이터베이스를 초기화합니다.이 전에는 파일이 백업된 DB를 사용하는 것이 유일한 방법이었습니다.그러나 이로 인해 클라우드 구현 시 지연 시간 문제가 발생했습니다.
"database.py " 만들기:
import sqlite3
def dbcon():
return sqlite3.connect("your.db")
그런 다음 가져오기:
from database import dbcon
db = dbcon()
db.execute("INSERT INTO users(name,email,username,password)
VALUES(?,?,?,?)", (name, email, username, password))
실이 바로 끊어지기 때문에 닫지 않아도 될 것입니다.
언급URL : https://stackoverflow.com/questions/48218065/objects-created-in-a-thread-can-only-be-used-in-that-same-thread
'programing' 카테고리의 다른 글
새 데이터베이스 서버로 마이그레이션됨. 동일한 쿼리가 매우 느림 (0) | 2023.09.25 |
---|---|
Qt5.11.2, iMAC 상의 QSql 데이터베이스 및 MariaDB (0) | 2023.09.25 |
NULL 입력 파라미터를 Oracle 저장 프로시저로 제한하는 방법 (0) | 2023.09.25 |
AntiXss의 차이점은 무엇입니까?HtmlEncode 및 HttpUtility.htmlEncode? (0) | 2023.09.25 |
워드프레스 웹사이트에 .exe 파일 업로드하기 (0) | 2023.09.25 |