SQLite3拆分数据库操作到独立函数时出现NoneType无cursor属性报错如何解决
错误原因与修复方案
核心报错根因
你遇到的AttributeError: 'NoneType' object has no attribute 'cursor'是两个错误共同导致的:
- 主函数中调用
create_connection后没有把返回的连接对象赋值给db变量,你预先定义的db = None没有被覆盖,传给create_table的参数本身就是空值 create_connection函数内部的finally逻辑错误:刚连接成功就直接关闭了数据库连接,就算你接住返回值,拿到的也是无效的已关闭连接
其他隐藏问题
你写的建表SQL还有语法错误,就算连接正常也会执行失败:
Company表的CompanyName字段定义末尾多了多余的逗号Employee、Meeting表的外键约束声明前没有加逗号,语法不合法
修复后完整代码
import sqlite3 from sqlite3 import Error def create_connection(CRM): """ 检查数据库文件是否存在,不存在则自动创建,返回有效的数据库连接对象 :param CRM: 数据库文件路径 :return: sqlite3连接对象,创建失败返回None """ db = None try: db = sqlite3.connect(CRM) print(sqlite3.version) # 开启外键约束,否则sqlite默认不检查外键关联 db.execute("PRAGMA foreign_keys = ON") except Error as e: print(e) # 删掉原来的finally关闭逻辑,连接交给调用方管理 return db def create_table(db): cur = db.cursor() G8Personnel = ''' CREATE TABLE IF NOT EXISTS G8Personnel( DoD INTEGER NOT NULL PRIMARY KEY, Rank varchar NOT NULL, FirstName varchar NOT NULL, LastName varchar NOT NULL, Role varchar NOT NULL )''' cur.execute(G8Personnel) # 删掉字段末尾多余的逗号 Company = '''CREATE TABLE IF NOT EXISTS Company( CompanyName varchar PRIMARY KEY )''' cur.execute(Company) # 外键约束前加逗号 Employee = '''CREATE TABLE IF NOT EXISTS Employee( AutoID INTEGER PRIMARY KEY AUTOINCREMENT, FirstName varchar NOT NULL, LastName varchar NOT NULL, Email varchar NOT NULL, JobTitle varchar, WebPage varchar, Notes varchar, Company varchar, FOREIGN KEY (Company) REFERENCES Company(CompanyName) )''' cur.execute(Employee) # 外键约束前加逗号 Meeting = '''CREATE TABLE IF NOT EXISTS Meeting( AutoID INTEGER PRIMARY KEY AUTOINCREMENT, Date1 real NOT NULL, DoD INTEGER NOT NULL, Employee INTEGER NOT NULL, MeetingNotes varchar NOT NULL, FOREIGN KEY (DoD) REFERENCES G8Personnel (DoD), FOREIGN KEY (Employee) REFERENCES Employee (AutoID) )''' cur.execute(Meeting) # 提交建表操作 db.commit() if __name__ == '__main__': # 接收连接对象返回值 db = create_connection(r'C:\Users\c94re\Documents\Git-Repo\CRM\CRM.db') if db: # 加个判断,连接创建成功再建表 create_table(db) # 所有操作完成后再关闭连接 db.close()
注意事项
- 数据库连接要在所有操作完成后再关闭,不要提前关闭
- 所有写操作完成后要调用
commit()提交,否则修改不会持久化到磁盘 - SQLite默认关闭外键约束,需要手动执行
PRAGMA foreign_keys = ON开启才能生效
内容的提问来源于stack exchange,提问作者RogueGingerz
相关产品推荐
相关产品推荐

