根据SQLAlchemy,在for循环中,将select语句视为可迭代。结果是将返回大量行的select语句不会使用过多的内存。
我在MySQL表上发现以下语句:
for row in my_connections.execute(MyTable.__table__.select()):
yield row
似乎不遵循此要求,因为我溢出了可用内存并在产生第一行之前开始崩溃。我究竟做错了什么?
基本MySQLdb
游标立即从服务器获取整个查询结果。这会消耗大量内存和时间。当您要进行大型查询并一次从服务器提取结果时,请使用MySQLdb.cursors.SSCursor。
因此,connect_args={'cursorclass': MySQLdb.cursors.SSCursor}
在创建时尝试传递engine
:
from sqlalchemy import create_engine, MetaData
import MySQLdb.cursors
engine = create_engine('mysql://root:zenoss@localhost/e2', connect_args={'cursorclass': MySQLdb.cursors.SSCursor})
meta = MetaData(engine, reflect=True)
conn = engine.connect()
rs = s.execution_options(stream_results=True).execute()
参见http://www.sqlalchemy.org/trac/ticket/1089
请注意,使用SSCursor会锁定表,直到提取完成。这会影响使用同一连接的其他游标:来自同一连接的两个游标不能同时从表中读取。
但是,来自不同连接的游标可以同时从同一表中读取。
这是一些演示问题的代码:
import MySQLdb
import MySQLdb.cursors as cursors
import threading
import logging
import config
logger = logging.getLogger(__name__)
query = 'SELECT * FROM huge_table LIMIT 200'
def oursql_conn():
import oursql
conn = oursql.connect(
host=config.HOST, user=config.USER, passwd=config.PASS,
db=config.MYDB)
return conn
def mysqldb_conn():
conn = MySQLdb.connect(
host=config.HOST, user=config.USER,
passwd=config.PASS, db=config.MYDB,
cursorclass=cursors.SSCursor)
return conn
def two_cursors_one_conn():
"""Two SSCursors can not use one connection concurrently"""
def worker(conn):
cursor = conn.cursor()
cursor.execute(query)
for row in cursor:
logger.info(row)
conn = mysqldb_conn()
threads = [threading.Thread(target=worker, args=(conn, ))
for n in range(2)]
for t in threads:
t.daemon = True
t.start()
# Second thread may hang or raise OperationalError:
# File "/usr/lib/pymodules/python2.7/MySQLdb/cursors.py", line 289, in _fetch_row
# return self._result.fetch_row(size, self._fetch_type)
# OperationalError: (2013, 'Lost connection to MySQL server during query')
for t in threads:
t.join()
def two_cursors_two_conn():
"""Two SSCursors from independent connections can use the same table concurrently"""
def worker():
conn = mysqldb_conn()
cursor = conn.cursor()
cursor.execute(query)
for row in cursor:
logger.info(row)
threads = [threading.Thread(target=worker) for n in range(2)]
for t in threads:
t.daemon = True
t.start()
for t in threads:
t.join()
logging.basicConfig(level=logging.DEBUG,
format='[%(asctime)s %(threadName)s] %(message)s',
datefmt='%H:%M:%S')
two_cursors_one_conn()
two_cursors_two_conn()
请注意,oursql是Python的另一套MySQL绑定。oursql游标是真正的服务器端游标,默认情况下会延迟获取行。随着oursql
安装,如果你改变
conn = mysqldb_conn()
至
conn = oursql_conn()
然后two_cursors_one_conn()
运行而不会挂起或引发异常。
问题内容: MySql中有没有一种方法可以创建用于联接的内联表? 就像是: 那会输出 我可以在这样的联接中使用: 我意识到我可以做到 但这似乎很邪恶 我不想执行存储过程,因为在每次查询和数据大小上,a,b,c都可能发生变化。另外,存储过程也需要保存在数据库中,我不想只为此修改数据库。视图是一回事。 我真正想要的是使用更好的语法的东西。 问题答案: 我真正在寻找的是使用更好的语法执行SELECT 1
问题内容: 我在C#项目中将SQLServer用于故障排除程序,并且我有一个包含ID,Question,QuestionId,Solution和Rank的表。我希望有一个问题的多个解决方案,并且程序将选择排名最高的解决方案,该解决方案仅由最高的数字来选择,该数字在每次正确时都会递增。为此,我有以下SQL语句: 当我只有一个可用的解决方案时,它可以很好地工作,但是当我有多个解决方案时,它却不能。 问
问题内容: 我正在浏览tour.golang.org中的示例,并且遇到了我不太了解的这段代码: 我了解通道工作的基础知识,但是我没有得到的是上述select语句的工作方式。教程中的说明说: “ select语句使goroutine等待多个通信操作。一个select阻塞直到它的一种情况可以运行,然后它执行该情况。如果有多个就绪,它将随机选择一个。” 但是案件如何执行?据我所知,他们在说: 案例:发送
问题内容: 刚尝试去最近。我想知道如果您有一条select语句等待在几个通道上进行通信,并且如果消息同时在两个或多个通道上出现,将会发生什么情况。如果所有消息都同时发出,那么select将如何确定接受哪个通道? 谢谢! 问题答案: 从规格: 如果可能发生多种情况,则将做出统一的伪随机选择,以决定执行哪个单一通信。 因此,选择是不确定的。
问题内容: 我基本上有两个名为和的表。该表具有以下字段: 是表中字段的外键,其中包含以下字段: 我正在运行这样的查询: 除其他事项外,这将返回用户的。但是我想返回用户的用户名,而不是他们的u_id。因此,基本上,在该SELECT语句中,我还想运行: 我可以为此使用两个查询,但是我试图减少我的应用程序运行的查询,而且我知道有一种方法可以将其组合成一个查询,但是我只是不知道:< 有人知道答案吗?谢谢!
【内存占用】页面主要展示项目运行过程中内存的使用情况,主要包括以下几个部分: 数据汇总 该项主要展示项目运行过程中的 “总内存峰值”、“堆内存峰值”、“GFX内存峰值” 和 “泄露风险”。其中,总内存为Unity引擎所统计的真实物理内存分配,并不包含系统缓存和第三方库的自身分配内存; 堆内存所指的是 Mono 管理和分配的托管堆内存; GFX内存为用于渲染的资源所占用的内存,主要包括纹理资源、网格