Ошибка программирования: Объект был создан с идентификатором потока 14408, а это идентификатор потока 2776. Я не могу создать учетную запись

#python #database #sqlite #streamlit

Вопрос:

**Проект с потоковым освещением: Ошибка ниже появляется каждый раз, когда я создаю учетную запись. Я тоже не знаю, где я ошибаюсь. Пожалуйста, мне нужна помощь **

МОЙ основной код

 import streamlit as st

# EDA PKG
import numpy as np
import pandas as pd

# UTILS
import os
import joblib
import hashlib # you can also use passlib and bcrypt

# VISUALISATION PKG
import matplotlib.pyplot as plt
import matplotlib
import seaborn as sns
matplotlib.use('Agg')

# DATABASE
from manage_db_1 import *

# Password
def generate_hashes(password):
    return hashlib.sha256(str.encode(password)).hexdigest()

# Verify password
def verify_hashes(password, hashed_text):
    if generate_hashes(password) == hashed_text:
        return hashed_text
    return False

# Interface

def main():
    """Mortality Prediction App"""
    st.title("Disease Mortality Prediction App")
    
    menu = ['Home', 'Login', 'Signup']
    submenu = ['Plot','Prediction', 'Metrics']
    
    choice = st.sidebar.selectbox("Menu", menu)
    if choice == "Home":
        st.subheader("Home")
        st.write("What is Hepatitis?")
    elif choice == "Login":
        username = st.text_input("Username")
        password = st.text_input("Password", type="password")
        if st.sidebar.checkbox("Login"):
            create_usertable(username1,password1)
            hashed_pswd = generate_hashes(password)
            result = login_user(username, verify_hashes(password, hashed_pswd))
            #if password =="12345":
            if result:
                st.success("Welcome {}".format(username))
                
                activity = st.selectbox("Activity", submenu)
                if activity == "Plot":
                    st.subheader("Data Visualisation Plot")
                    
                elif activity == "Prediction":
                    st.subheader("Predictive Analytics")               
                
            else:
                st.warning("Incorrect Username/Password")
            
    elif choice == "Signup":
        new_username = st.text_input("User Name")
        new_password = st.text_input("Password", type='password')
        confirmed_password = st.text_input("Confirm Password", type='password')
        if new_password == confirmed_password:
            st.success("Password Confirmed")
        else:
            st.warning("Passwords not the same")
        if st.button("Submit"):
            create_usertable()
            hashed_new_password = generate_hashes(new_password)
            add_userdata(new_username, hashed_new_password)
            st.success("You have successfully created a new account")
            st.info("Login To Get Started")             
    
if __name__ == '__main__':
    main()
 

Код базы данных

 import sqlite3
conn = sqlite3.connect("usersdata.db")
c = conn.cursor()


# FXN
def create_usertable():
    #c.execute('CREATE TABLE IF NOT EXISTS userstable(username, password)')
    c.execute('CREATE TABLE IF NOT EXISTS userstable(username TEXT, password TEXT)')
    
def add_userdata(username, password):
    c.execute('INSERT INTO userstable(username,password) VALUES (?,?)', (username,password))
    conn.commit()


def login_user(username, password):
    #c.execute('SELECT.*.FROM.userstable.WHERE.username.=?.AND.password.=?',(username,password))
    #data.=c.fetchall()
    #return.data
    c.execute('SELECT * FROM userstable WHERE username =? AND password =?',(username,password))
    data = c.fetchall()
    return data
    
    
def view_all_users():
    c.execute('SELECT * FROM userstable')
    data = c.fetchall()
    return data
 

Ошибка программирования: объекты SQLite, созданные в потоке, могут использоваться только в этом же потоке. Объект был создан с идентификатором потока 14408, а это идентификатор потока 2776.

 Traceback:
File "c:userseli.condaenvselilibsite-packagesstreamlitscript_runner.py", line 354, in _run_script
    exec(code, module.__dict__)
File "C:UsersEliDocumentsbetes.py", line 89, in <module>
    main()
File "C:UsersEliDocumentsbetes.py", line 82, in main
    create_usertable()
File "C:UsersEliDocumentsmy_db.py", line 12, in create_usertable
    c.execute("CREATE TABLE IF NOT EXISTS userstable(username TEXT, password TEXT)")```
 

Ответ №1:

По умолчанию объекты Python sqlite3, такие как соединения и курсоры, могут использоваться только в потоке, который их создает. Очевидно, script_runner.py что streamlit выполняет код вашей базы данных в нескольких потоках.

Решение заключается в создании соединений и курсоров внутри функций базы данных. Чтобы уменьшить дублирование, вы можете вызвать execute соединение напрямую, например:

 def login_user(username, password):
    with sqlite3.connect("usersdata.db") as conn:
        data = list(
            conn.execute('SELECT * FROM userstable WHERE username =? AND password =?',
                     (username,password)))
    conn.close()
    return data
 

Можно отключить ограничение, используя объекты в нескольких потоках, перейдя check_same_thread=False к connect функции. Однако было бы неразумно делать это из-за риска повреждения данных.

Комментарии:

1. Но, пожалуйста, ошибка связана с регистрацией. И из базы данных он указал на создание таблицы. def create_usertable(): c.execute('CREATE TABLE IF NOT EXISTS userstable(username TEXT, password TEXT)')

2. Вы не можете иметь conn или c в качестве глобальных переменных. Вам нужно создать их внутри каждой из функций базы данных.

3. Я создал их в каждой из функций, но получил одно и то же сообщение об ошибке. Я был бы рад, если бы вы могли направить меня в этом отношении на данном примере.

4. Ах, в моем коде была опечатка — должно быть conn.execute , нет c.excecute .

5. Возможно, я не все понял правильно, пожалуйста, проверьте код и поправьте меня.