#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. Возможно, я не все понял правильно, пожалуйста, проверьте код и поправьте меня.