Python代码本地运行正常,嵌入PyScript时出现AttributeError错误求助
报错信息
Traceback (most recent call last):
File "/lib/python3.10/site-packages/_pyodide/_base.py", line 435, in eval_code
.run(globals, locals)
File "/lib/python3.10/site-packages/_pyodide/_base.py", line 304, in run
coroutine = eval(self.code, globals, locals)
File "", line 3, in
File "/home/pyodide/connection_sqlite3.py", line 45, in returnGeral
data = cursor.execute(r"SELECT * FROM tabela;")
AttributeError: 'NoneType' object has no attribute 'execute'
问题根源分析
1. 数据库路径与PyScript沙箱不兼容
本地Python运行时,data/tutorial.db是相对于脚本的路径,但PyScript运行在浏览器的Pyodide沙箱中,本地的data目录和数据库文件不会自动加载到沙箱环境,导致sqlite3.connect()调用失败,connection()函数返回None。
2. 代码逻辑错误
connection()函数返回数据库连接对象,但多个函数(如returnGeral、insertData)错误地将其赋值给cursor变量,混淆了连接对象和游标对象的概念。- 部分函数重复调用
connection()创建多个独立连接,导致事务提交等操作失效;且错误处理时未明确返回值,隐式返回None。
修复方案
步骤1:配置数据库文件加载
在py-config中添加数据库文件的fetch规则,将本地数据库加载到沙箱中:
<py-config> [[fetch]] from = 'data/' files = ['tutorial.db'] [[fetch]] from = 'scripts/' files = ['connection_sqlite3.py'] </py-config>
步骤2:修正代码逻辑
修改connection_sqlite3.py中的函数,明确区分连接与游标,添加连接检查:
修正后的完整connection_sqlite3.py
import sqlite3 from sqlite3 import Error # 沙箱中数据库已在根目录,无需data/前缀 data = 'tutorial.db' # 读取SQL模板文件 def templates(arquivo): try: with open(arquivo, 'r') as raw: edited = raw.read() return edited except Error as e: print(f"读取模板文件失败: {e}") return None # 创建数据库连接 def connection(): try: conn = sqlite3.connect(data) return conn except Error as e: print(f"连接数据库失败: {e},行号14") return None # 创建表 def createTable(archive): try: conn = connection() if not conn: return cursor = conn.cursor() cursor.execute(archive) conn.commit() print("表创建成功") except Error as e: print(f"创建表失败: {e},行号23") # 插入数据 def insertData(param): try: conn = connection() if not conn: return cursor = conn.cursor() cursor.execute(param) conn.commit() print(f"{param} 已成功插入表中" ) except Error as e: print(f"插入失败: {e},行号41") # 查询所有数据 def returnGeral(): try: conn = connection() if not conn: print("数据库连接失败,无法执行查询") return None cursor = conn.cursor() cursor.execute(r"SELECT * FROM tabela;") raw = cursor.fetchall() for i in raw: print(i) return raw except Error as e: print(f"查询失败: {e},行号34") return None # 执行自定义SQL def execute(param): try: conn = connection() if not conn: return cursor = conn.cursor() cursor.execute(param) conn.commit() print(f'{param} 执行成功') except Error as e: print(f"执行失败: {e},行号64")
步骤3:匹配项目文件结构
确保项目目录结构如下:
项目根目录/ ├── index.html ├── data/ │ └── tutorial.db └── scripts/ ├── main.py └── connection_sqlite3.py
完整修正后的HTML代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>index</title> <link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" /> <link rel="stylesheet" type="text/css" href="style/style.css"> <script defer src="https://pyscript.net/latest/pyscript.js"></script> </head> <body> <py-config> [[fetch]] from = 'data/' files = ['tutorial.db'] [[fetch]] from = 'scripts/' files = ['connection_sqlite3.py'] </py-config> <py-script src="scripts/main.py"></py-script> <div id="principal"> <div id="navegation"> <input placeholder="teste" type="text"> <button py> search </button> </div> <div id="table"> </div> </div> </body> </html>
内容的提问来源于stack exchange,提问作者Recknover

