直到昨天,我还在为我的应用程序使用SQLite。今天我找到了一个足够强大的理由(多个应用程序实例),可以使用pymysql
切换到MySQL。
有一次,我的应用程序在数据库中查询了300行:
cur.execute('select ime,brPredmeta,statusStr,sudskiBr ,sudija ,datumRasprave,statusPredmeta, zaduzen,datumZaduzenja from predmeti')
sviaktivni = cur.fetchall()
sviaktivni = list(sviaktivni) #make a list of tuples
sviaktivni.sort(key=operator.itemgetter(0)) #sort the list
之后,我提取变量,然后使用这些变量制作HTML文档,然后将其发送到打印机(PDF或普通打印机)。生成HTML的代码非常简单; “header”(为清晰起见,此处省略)的几行表,然后是“body”的另一个表,代码如下:
#extract the variables
for tuple in sviaktivni:
ime,brPredmeta,statusStr,sudskiBr ,sudija ,datumRasprave,statusPredmeta, zaduzen,datumZaduzenja = tuple
#done extracting
body = ('<html><head><title></title>'
'<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>'
'<style></style>'
'</head>'
'<body>'
'<table align ="center" border="0" width="100%" style="table-layout:fixed">'
'<tr height="10%">'
'<td align="left" width="20">'+str(brojac)+'.</td>'
'<td align="left" width="180">'+ime+'</td>'
'<td align="left" width="100">'+str(brPredmeta)+'</td>'
'<td align="left" width="80">'+statusStr+'</td>'
'<td align="left" width="80">'+str(sudskiBr)+'</td>'
'<td align="left" width="140">'+sudija+'</td>'
'<td align="left" width="150">'+zaduzen+'</td>'
'<td align="left">'+datumZaduzenja+'</td>'
'<td align="right"> '+statusPredmeta+' </td>'
'</tr>'
'</table>'
'</body>'
'</html>')
self.ui.printHTML.append(body)
我的问题是查询是立即执行的,但是在CPU停留在100%之后,整个程序就冻结了。打印预览对话框有时会显示数据,有时它只是一个空窗口。无论哪种方式,整个应用程序都被冻结。
使用SQLite的相同代码没有问题。我该怎么办?回到sqlite并冒险数据库损坏?
答案 0 :(得分:1)
不要只将整个SQL结果加载到内存中,并希望这适用于所有情况。此外,使用数据库为您进行排序,这就是它的优点。
只需循环遍历游标并逐个处理结果,这样就不必用中间结果填充内存:
cur.execute('''
select
ime, brPredmeta, statusStr, sudskiBr, sudija,
datumRasprave,statusPredmeta, zaduzen,datumZaduzenja
from predmeti
order by ime
''')
for row in cur:
ime, brPredmeta, statusStr, sudskiBr, sudija, datumRasprave, statusPredmeta, zaduzen, datumZaduzenja = row
# Process row data.
答案 1 :(得分:0)
取自SQLite Docs ...
可以是多个应用程序或多个相同的实例 应用程序同时访问单个数据库文件?
多个进程可以同时打开同一个数据库。 多个进程可以同时执行SELECT。但是只有 一个进程可以随时对数据库进行更改 然而,时间。
SQLite使用读取器/写入器锁来控制对数据库的访问。 (在Win95 / 98 / ME下,缺少对读写器锁的支持,a 改为使用概率模拟。)但要谨慎:这个 如果数据库文件是,锁定机制可能无法正常工作 保存在NFS文件系统上。这是因为fcntl()文件锁定是 在许多NFS实现上打破了。你应该避免使用SQLite NFS上的数据库文件,如果多个进程可能尝试访问 同时提交文件。在Windows上,微软的文档说明了这一点 如果您没有运行,则锁定在FAT文件系统下可能无法正常工作 Share.exe守护程序。对Windows有很多经验的人 告诉我,网络文件的文件锁定是非常错误的,而不是 可信。如果他们说的是真的,那就共享一个SQLite数据库 两台或多台Windows机器之间可能会出现意外问题。
我们知道没有其他支持as的嵌入式SQL数据库引擎 和SQLite一样多并发。 SQLite允许多个进程拥有 数据库文件立即打开,并为多个进程读取 数据库一下子。当任何进程想要写入时,它必须锁定 整个数据库文件的更新期间。但通常情况下 只需几毫秒。其他进程只是等待作者 完成然后继续他们的业务。其他嵌入式SQL 数据库引擎通常只允许单个进程连接 数据库一下子。
但是,客户端/服务器数据库引擎(例如PostgreSQL,MySQL或 Oracle)通常支持更高级别的并发和允许 多个进程要同时写入同一个数据库 时间。这在客户端/服务器数据库中是可能的,因为存在 始终是一个可以协调的良好控制的服务器进程 访问。如果您的应用程序需要大量并发,那么 您应该考虑使用客户端/服务器数据库。但经验 表明大多数应用程序需要的并发性要比它们少得多 设计师想象。
当SQLite尝试访问被另一个进程锁定的文件时, 默认行为是返回SQLITE_BUSY。你可以调整它 使用sqlite3_busy_handler()或来自C代码的行为 sqlite3_busy_timeout()API函数。