2011-01-06 53 views
7

我想我会尝试让我的sqlite数据库连接的功能,而不是复制/粘贴连接和执行查询所需的〜6行。 我想使它多才多艺,所以我可以使用相同的功能创建/选择/插入/等...我可以将我的sqlite连接和游标放在函数中吗?

以下是我所尝试过的。 'INSERT'和'CREATE TABLE'查询正在工作,但是如果我做了'SELECT'查询,我该如何处理它在函数外部获取的值?
通常我想打印它提取的值,也可以用它们做其他事情。

当我不喜欢它下面我得到一个错误

Traceback (most recent call last): 
File "C:\Users\steini\Desktop\py\database\test3.py", line 15, in <module> 
for row in connection('testdb45.db', "select * from users"): 
ProgrammingError: Cannot operate on a closed database. 

所以我猜这个连接必须是开放的,所以我可以从游标的值,但我需要关闭它,该文件ISN永远不会锁定。

这里是我的测试代码:

import sqlite3 

def connection (db, arg, cubby): 
    conn = sqlite3.connect(db) 
    conn.execute('pragma foreign_keys = on') 
    cur = conn.cursor() 
    cur.execute(arg) 
    for row in cur: 
     cubby.append(row) 
    conn.commit() 
    conn.close() 

cubby=[] 
connection('testdb.db', "create table users ('user', 'email')", cubby) 
connection('testdb.db', "insert into users ('user', 'email') values ('joey', '[email protected]')", cubby) 
for row in connection('testdb45.db', "select * from users", cubby): 
    print row 

我怎样才能使这项工作?

编辑:修改了代码,那么一点点的CUR值,所以它附加到外部列表中,但仍然很糟糕

回答

15

我认为这个问题是比起初看上去有点难度。

由于您在“连接”功能中关闭了与数据库的连接,因此您会看到该错误。

您可能最好创建一个DatabaseManagement类来管理单个连接。

喜欢的东西:

import sqlite3 

class DatabaseManager(object): 
    def __init__(self, db): 
     self.conn = sqlite3.connect(db) 
     self.conn.execute('pragma foreign_keys = on') 
     self.conn.commit() 
     self.cur = self.conn.cursor() 

    def query(self, arg): 
     self.cur.execute(arg) 
     self.conn.commit() 
     return self.cur 

    def __del__(self): 
     self.conn.close() 

那么你应该能够做这样的事情:

dbmgr = DatabaseManager("testdb.db") 
for row in dbmgr.query("select * from users"): 
    print row 

这将保持连接打开的对象存在的持续时间。

你仍然可能会发现这是一个更深层次的问题,但请仔细观察,看看有什么适用于你。

+0

真棒,我将不得不再次混淆它,但到目前为止,这个类似乎对我所做的完美工作。谢谢 – 2011-01-06 01:26:13

+1

Minor nit,但你需要:在第二个代码块中的for语句后:) – 2017-04-29 14:21:25

0

这是失败的,因为你的函数在返回之前关闭连接。解决这个问题的方法是将函数转换为传递结果的生成器。像下面的未经测试的代码的东西应该工作:

def connection (db, arg): 
    conn = sqlite3.connect(db) 
    conn.execute('pragma foreign_keys = on') 
    cur = conn.cursor() 
    cur.execute(arg) 
    for row in cur: 
     yield row 
    conn.commit() 
    conn.close() 

你必须要格外小心调用此功能时消耗的所有行,因为如果你不那么该连接不会被关闭。您可以通过查看执行with语法所需的功能来避免此问题。