如何在main.py中调用db.py封装的sqlite3连接与游标执行cursor.execute查询?
解答
你最初写db.self.cur.execute报错的原因:self是Python类内部指代实例本身的关键字,你在main.py中实例化Database类得到db对象后,db本身就对应类内部的self,不需要再加一层.self,直接访问实例属性即可,这也是你调整为db.cur.execute后不再报属性错误的原因。
问题1:sqlite3.connect的db参数是否需要填写完整路径?
不需要强制填写绝对路径,你可以传相对路径,也可以传绝对路径,两者区别如下:
- 传相对路径时,路径是相对于你执行Python脚本时的终端工作目录,不是相对于main.py或db.py的文件存放目录。比如你在
/home/目录下运行python xxxx/main.py,相对路径就会以/home/为基准拼接,很容易出现找不到数据库或者在错误位置新建数据库的问题。 - 传绝对路径可以固定数据库的读取/生成位置,不会受执行脚本的工作目录影响,稳定性更高。如果不想写死绝对路径,也可以在代码里通过
os.path模块动态拼接项目根目录的绝对路径,适配不同部署环境。
问题2:正确的跨文件调用游标执行查询的写法是什么?
你调整后的写法已经是可运行的合法写法,工程上通常根据场景选择两种实现方式:
写法1:直接访问实例游标(小型项目/简单场景用)
和你调整后的写法一致,游标执行后可以用内置的fetchall/fetchone/fetchmany方法更清晰地获取结果,示例:
# main.py 完整可运行写法 from db import Database db = Database('/home/xxxx/database.db') def example(): db.cur.execute('SELECT Name FROM TableExample') # 直接获取所有查询结果的第一列,等价于遍历游标的写法,可读性更高 result = [row[0] for row in db.cur.fetchall()] return result
写法2:封装查询方法(中大型项目推荐)
不要直接对外暴露连接、游标这类底层属性,在Database类里封装操作方法,统一处理异常、资源管理,示例:
# db.py 新增封装方法 import sqlite3 class Database: def __init__(self, db): self.con = sqlite3.connect(db) self.cur = self.con.cursor() sql = """ CREATE TABLE IF NOT EXISTS employees( ID Integer Primary Key, example1 integer, example2 integer ) """ self.cur.execute(sql) self.con.commit() # 新增通用查询方法 def query(self, sql, params=None): params = params or () try: self.cur.execute(sql, params) self.con.commit() return self.cur.fetchall() except Exception as e: self.con.rollback() raise e
# main.py 调用时不需要直接操作游标 from db import Database db = Database('/home/xxxx/database.db') def example(): result = [row[0] for row in db.query('SELECT Name FROM TableExample')] return result
这种写法可以避免外部误操作游标、连接,后续如果要替换数据库驱动也不需要修改所有调用的地方。
内容的提问来源于stack exchange,提问作者Erling Olsen
相关产品推荐
相关产品推荐

