如何使SQLAlchemy中Tornado是async?我在async mongo示例中找到了MongoDB的示例,但我找不到类似motor的内容SQLAlchemy.有没有人知道如何SQLAlchemy执行查询tornado.gen(我在MySQL下面使用SQLAlchemy,目前我的处理程序从数据库读取并返回结果,我想使这个异步).
我想描述(密切关注)PostgreSQL中数据库中发生的所有活动.
有没有这样的实用程序可以帮助我这样做?
我创建了一个客户端应用程序,它使用HTTP通过简单的API与Python 2服务器通信.服务器非常广泛地使用SQLAlchemy的ORM来为这些HTTP请求提供数据.问题是即使只有很少的活动客户端,我的CPU使用率也很高.该服务器应该能够同时为每个客户端提供大约1个请求,同时为几百个客户端提供服务,因此它仍然应该是可管理的(或者我希望如此).
如何提高性能?我知道问题是ORM,因为cProfile非常清楚地表明了这一点.单个查询显然执行大约10000个Python指令,这看起来很奇怪.我尝试插入不同的数据库引擎/后端,并将解释器更改为Pypy只是为了好玩,但它显然没有帮助原始问题,也没有提高性能.
我在这做错了什么?我真的希望这是一个"好吧,呃!" 问题.
我的关系应该是不同的类型吗?渴望,懒惰,动态等?现在,我没有特别说明.
非常感谢.
我花了一天时间尝试在Python脚本中调试内存问题.我正在使用SQL Alchemy作为我的ORM.这里有几个令人困惑的问题,我希望如果我把它们全部列出来,有人可以指出我正确的方向.
为了达到我正在寻找的性能,我读了一张表中的所有记录(~400k),然后遍历电子表格,匹配我之前读过的记录,然后创建新记录(~800k)进入另一张桌子.这大致是代码的样子:
dimensionMap = {}
for d in connection.session.query(Dimension):
dimensionMap[d.businessKey] = d.primarySyntheticKey
# len(dimensionMap) == ~400k, sys.getsizeof(dimensionMap) == ~4MB
allfacts = []
sheet = open_spreadsheet(path)
for row in sheet.allrows():
dimensionId = dimensionMap[row[0]]
metric = row[1]
fact = Fact(dimensionId, metric)
connection.session.add(fact)
allfacts.append(fact)
if row.number % 20000 == 0:
connection.session.flush()
# len(allfacts) == ~800k, sys.getsizeof(allfacts) == ~50MB
connection.session.commit()
sys.stdout.write('All Done')
Run Code Online (Sandbox Code Playgroud)
400k和800k对我来说似乎不是特别大的数字,但我仍然遇到内存问题,一台4GB内存的机器.这对我来说真的很奇怪,因为我在我的两个最大的集合上运行了sys.getsizeof,它们都处于任何可能导致问题的大小之下.
在试图解决这个问题时,我注意到脚本运行的确非常非常慢.所以我在其上运行了一个配置文件,希望结果会引导我朝向内存问题的方向,并提出两个混淆问题.

首先,87%的程序时间花在提交上,特别是在这行代码上:
self.transaction._new[state] = True
Run Code Online (Sandbox Code Playgroud)
这可以在session.py:1367. self.transaction._new是一个实例weakref.WeakKeyDictionary().为什么weakref:261:__setitem__要占用这么多时间?
其次,即使程序完成('All Done'已经打印到stdout),脚本仍在继续,看似永远,使用了2.2GB的内存.
我已经对weakrefs进行了一些搜索,但没有看到有人提到我面临的性能问题.最终,由于它被深埋在SQL Alchemy中,我无法做很多事情,但是我仍然很欣赏任何想法.
正如@zzzeek所提到的,维护持久对象需要很多开销.这是一个显示增长的小图表. …
如何在category_id删除类别时自动将产品设置为默认值?例如1,指向第一个类别.
class Product(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80))
content = db.Column(db.Text(), unique=True)
category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
atime = db.Column(db.DateTime())
def __init__(self, name, content, category_id):
self.name = name
self.content = content
self.category_id = category_id
self.atime = datetime.now()
def __repr__(self):
return '<Product %r>' % self.id
class Category(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80))
products = db.relationship('Product', backref='category', cascade="all, delete, delete-orphan")
def __init__(self, *args, **kwargs):
if len(kwargs) > 0:
self.name = kwargs['name']
def __repr__(self):
return '<Category …Run Code Online (Sandbox Code Playgroud) 在我看来,通过创建表达式树的整个过程,然后再次创建一个查询是使用sqlalchemy时浪费的时间.除了偶尔的动态查询之外,在应用程序的整个生命周期中几乎所有内容都是完全相同的(除了参数当然).
有没有办法在创建查询后保存查询并在以后使用不同的参数重新使用它?或者也许有一些内部机制已经做了类似的事情?
python ×5
sqlalchemy ×5
caching ×1
memory-leaks ×1
monitoring ×1
postgresql ×1
profiling ×1
python-2.7 ×1
sql ×1
tornado ×1