ProgrammingError:对象是在线程 id 14408 中创建的,这是线程 id 2776。我无法创建帐户

Posted

技术标签:

【中文标题】ProgrammingError:对象是在线程 id 14408 中创建的,这是线程 id 2776。我无法创建帐户【英文标题】:ProgrammingError: The object was created in thread id 14408 and this is thread id 2776. Am unable to create an account 【发布时间】:2021-11-14 15:10:02 【问题描述】:

**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

ProgrammingError: 在一个线程中创建的 SQLite 对象只能在同一个线程中使用。该对象是在线程 id 14408 中创建的,这是线程 id 2776。

Traceback:
File "c:\users\eli\.conda\envs\eli\lib\site-packages\streamlit\script_runner.py", line 354, in _run_script
    exec(code, module.__dict__)
File "C:\Users\Eli\Documents\betes.py", line 89, in <module>
    main()
File "C:\Users\Eli\Documents\betes.py", line 82, in main
    create_usertable()
File "C:\Users\Eli\Documents\my_db.py", line 12, in create_usertable
    c.execute("CREATE TABLE IF NOT EXISTS userstable(username TEXT, password TEXT)")```

【问题讨论】:

【参考方案1】:

默认情况下,连接和游标等 Python sqlite3 对象只能在创建它们的线程中使用。显然 streamlit 的 script_runner.py 正在多个线程中执行您的数据库代码。

解决方案是在数据库函数中创建连接和游标。为了减少重复,您可以在连接directly 上调用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 函数来禁用在多个线程中使用对象的限制。但是这样做是不明智的,因为存在数据损坏的风险。

【讨论】:

但是请注意,错误来自注册。而从数据库中,它指向了表的创建。 def create_usertable(): c.execute('CREATE TABLE IF NOT EXISTS userstable(username TEXT, password TEXT)') 您不能将connc 作为全局变量。您需要在每个数据库函数中创建它们。 我在每个函数中创建了它们,但有相同的错误消息。如果你能通过给定的例子在这方面指导我,我会很高兴。 啊,我的代码中有错字——应该是conn.execute,而不是c.excecute 可能是我写的不对,请检查代码并纠正我。

以上是关于ProgrammingError:对象是在线程 id 14408 中创建的,这是线程 id 2776。我无法创建帐户的主要内容,如果未能解决你的问题,请参考以下文章

Python支持SQL数据库返回psycopg2.ProgrammingError:在尝试删除表中的数据时,关系不存在错误?

pymysql.err.programmingError: (1064)

ProgrammingError:关系 django_session 的权限被拒绝

SQLAlchemy(psycopg2.ProgrammingError)无法适应类型'dict'

psycopg2.ProgrammingError:“st”或附近的语法错误\r,

psycopg2.ProgrammingError:语法错误