Streamlit - 在线程中创建的 SQLite 对象只能在同一个线程中使用
Streamlit - SQLite objects created in a thread can only be used in that same thread
我正在使用 Streamlit 作为我的数据处理和可视化框架。
按照 advanced caching with Streamlit 上的文档,关于如何创建数据库连接并将它们传递给其他函数,我正在使用 sqlite3
并尝试在 运行 上创建一个连接,并且通过 'cursor',方法是:
import streamlit as st
# create database connection
@st.cache(allow_output_mutation=True)
def get_database_connection():
conn = sqlite3.connect('collect/Data/fpl.db')
c = conn.cursor()
return c
这里我尝试通过 hash_funcs
传递我的连接 ID,返回创建的游标:
# pass connections around
@st.cache(allow_output_mutation=True, hash_funcs={sqlite3.Cursor:id})
def get_teams_basic(c):
df_teams = sql('SELECT * FROM TeamsBasic', c)
return df_teams
@st.cache(allow_output_mutation=True, hash_funcs={sqlite3.Cursor:id})
def get_players_basic(c):
df_player_basic = sql('SELECT * FROM PlayersBasic', c)
return df_player_basic
# and so on...
这是我的 sql()
:
def sql(query, cursor):
'''
Takes an SQL query string, and outputs a
dataframe representation of the query result.
'''
# Execute the sql query
cursor.execute(query)
# Get the query into a dataframe and set columns
df_temp = pd.DataFrame(cursor.fetchall())
df_temp.columns = [x[0] for x in cursor.description]
# Set the sql id as the dataframe index
index_column = df_temp.columns[0]
df_temp.set_index(index_column, drop=True, inplace=True)
return df_temp
然后,在 main()
,我实例化数据库连接并将光标传递给我的函数:
def main():
c = get_database_connection()
teams(c)
players(c)
if __name__ == '__main__':
main()
但是当代码到达第二个连接时,players()
我得到以下错误:
ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 123145444151296 and this is thread id 123145454661632.
回溯:
File "/Users/me/anaconda2/envs/data_science/lib/python3.7/site-packages/streamlit/ScriptRunner.py", line 322, in _run_script
exec(code, module.__dict__)
File "/Volumes/Dados/Documents/Code/Apps/app.py", line 280, in <module>
main()
File "/Volumes/Dados/Documents/Code/Apps/app.py", line 273, in main
managers(c)
File "/Volumes/Dados/Documents/Code/Apps/app.py", line 149, in managers
df_players = get_players_basic(c)
File "/Users/me/anaconda2/envs/data_science/lib/python3.7/site-packages/streamlit/caching.py", line 594, in wrapped_func
return get_or_create_cached_value()
File "/Users/me/anaconda2/envs/data_science/lib/python3.7/site-packages/streamlit/caching.py", line 578, in get_or_create_cached_value
return_value = func(*args, **kwargs)
File "/Volumes/Dados/Documents/Code/Apps/app.py", line 64, in get_players_basic
df_player_basic = sql('SELECT * FROM PlayersBasic', c)
File "/Volumes/Dados/Documents/Code/Apps/collect/PythonFunctions/sqlfunctions.py", line 111, in sql
cursor.execute(query)
我错过了什么?
我不确定您是否仍在解决此问题,但如果您正在解决,我发现了一个关于此主题的讨论线程可能有用。我很快就会在我的一个项目中试用它。
https://discuss.streamlit.io/t/prediction-analysis-and-creating-a-database/3504
我正在使用 Streamlit 作为我的数据处理和可视化框架。
按照 advanced caching with Streamlit 上的文档,关于如何创建数据库连接并将它们传递给其他函数,我正在使用 sqlite3
并尝试在 运行 上创建一个连接,并且通过 'cursor',方法是:
import streamlit as st
# create database connection
@st.cache(allow_output_mutation=True)
def get_database_connection():
conn = sqlite3.connect('collect/Data/fpl.db')
c = conn.cursor()
return c
这里我尝试通过 hash_funcs
传递我的连接 ID,返回创建的游标:
# pass connections around
@st.cache(allow_output_mutation=True, hash_funcs={sqlite3.Cursor:id})
def get_teams_basic(c):
df_teams = sql('SELECT * FROM TeamsBasic', c)
return df_teams
@st.cache(allow_output_mutation=True, hash_funcs={sqlite3.Cursor:id})
def get_players_basic(c):
df_player_basic = sql('SELECT * FROM PlayersBasic', c)
return df_player_basic
# and so on...
这是我的 sql()
:
def sql(query, cursor):
'''
Takes an SQL query string, and outputs a
dataframe representation of the query result.
'''
# Execute the sql query
cursor.execute(query)
# Get the query into a dataframe and set columns
df_temp = pd.DataFrame(cursor.fetchall())
df_temp.columns = [x[0] for x in cursor.description]
# Set the sql id as the dataframe index
index_column = df_temp.columns[0]
df_temp.set_index(index_column, drop=True, inplace=True)
return df_temp
然后,在 main()
,我实例化数据库连接并将光标传递给我的函数:
def main():
c = get_database_connection()
teams(c)
players(c)
if __name__ == '__main__':
main()
但是当代码到达第二个连接时,players()
我得到以下错误:
ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 123145444151296 and this is thread id 123145454661632.
回溯:
File "/Users/me/anaconda2/envs/data_science/lib/python3.7/site-packages/streamlit/ScriptRunner.py", line 322, in _run_script
exec(code, module.__dict__)
File "/Volumes/Dados/Documents/Code/Apps/app.py", line 280, in <module>
main()
File "/Volumes/Dados/Documents/Code/Apps/app.py", line 273, in main
managers(c)
File "/Volumes/Dados/Documents/Code/Apps/app.py", line 149, in managers
df_players = get_players_basic(c)
File "/Users/me/anaconda2/envs/data_science/lib/python3.7/site-packages/streamlit/caching.py", line 594, in wrapped_func
return get_or_create_cached_value()
File "/Users/me/anaconda2/envs/data_science/lib/python3.7/site-packages/streamlit/caching.py", line 578, in get_or_create_cached_value
return_value = func(*args, **kwargs)
File "/Volumes/Dados/Documents/Code/Apps/app.py", line 64, in get_players_basic
df_player_basic = sql('SELECT * FROM PlayersBasic', c)
File "/Volumes/Dados/Documents/Code/Apps/collect/PythonFunctions/sqlfunctions.py", line 111, in sql
cursor.execute(query)
我错过了什么?
我不确定您是否仍在解决此问题,但如果您正在解决,我发现了一个关于此主题的讨论线程可能有用。我很快就会在我的一个项目中试用它。
https://discuss.streamlit.io/t/prediction-analysis-and-creating-a-database/3504