简体   繁体   English

如何用sqlalchemy编写自己的聚合函数?

[英]How can I write my own aggregate functions with sqlalchemy?

How can I write my own aggregate functions with SQLAlchemy? 如何用SQLAlchemy编写自己的聚合函数? As an easy example I would like to use numpy to calculate the variance. 作为一个简单的例子,我想使用numpy来计算方差。 With sqlite it would look like this: 使用sqlite它看起来像这样:

import sqlite3 as sqlite
import numpy as np

class self_written_SQLvar(object):
  def __init__(self):
    import numpy as np
    self.values = []
  def step(self, value):
    self.values.append(value)
  def finalize(self):
    return np.array(self.values).var()

cxn = sqlite.connect(':memory:')
cur = cxn.cursor()
cxn.create_aggregate("self_written_SQLvar", 1, self_written_SQLvar)
# Now - how to use it:
cur.execute("CREATE TABLE 'mytable' ('numbers' INTEGER)")
cur.execute("INSERT INTO 'mytable' VALUES (1)") 
cur.execute("INSERT INTO 'mytable' VALUES (2)") 
cur.execute("INSERT INTO 'mytable' VALUES (3)") 
cur.execute("INSERT INTO 'mytable' VALUES (4)")
a = cur.execute("SELECT avg(numbers), self_written_SQLvar(numbers) FROM mytable")
print a.fetchall()
>>> [(2.5, 1.25)]

The creation of new aggregate functions is backend-dependant, and must be done directly with the API of the underlining connection. 新聚合函数的创建依赖于后端,必须直接使用下划线连接的API完成。 SQLAlchemy offers no facility for creating those. SQLAlchemy没有提供创建它们的工具。

However after created you can just use them in SQLAlchemy normally. 但是在创建之后,您通常可以在SQLAlchemy中使用它们。

Example: 例:

import sqlalchemy
from sqlalchemy import Column, Table, create_engine, MetaData, Integer
from sqlalchemy import func, select
from sqlalchemy.pool import StaticPool
from random import randrange
import numpy
import sqlite3

class NumpyVarAggregate(object):
  def __init__(self):
    self.values = []
  def step(self, value):
    self.values.append(value)
  def finalize(self):
    return numpy.array(self.values).var()

def sqlite_memory_engine_creator():
    con = sqlite3.connect(':memory:')
    con.create_aggregate("np_var", 1, NumpyVarAggregate)
    return con

e = create_engine('sqlite://', echo=True, poolclass=StaticPool,
                  creator=sqlite_memory_engine_creator)
m = MetaData(bind=e)
t = Table('mytable', m, 
            Column('id', Integer, primary_key=True),
            Column('number', Integer)
          )
m.create_all()

Now for the testing: 现在进行测试:

# insert 30 random-valued rows
t.insert().execute([{'number': randrange(100)} for x in xrange(30)])

for row in select([func.avg(t.c.number), func.np_var(t.c.number)]).execute():
    print 'RESULT ROW: ', row

That prints (with SQLAlchemy statement echo turned on): 打印(打开SQLAlchemy语句echo):

2009-06-15 14:55:34,171 INFO sqlalchemy.engine.base.Engine.0x...d20c PRAGMA 
table_info("mytable")
2009-06-15 14:55:34,174 INFO sqlalchemy.engine.base.Engine.0x...d20c ()
2009-06-15 14:55:34,175 INFO sqlalchemy.engine.base.Engine.0x...d20c 
CREATE TABLE mytable (
    id INTEGER NOT NULL, 
    number INTEGER, 
    PRIMARY KEY (id)
)
2009-06-15 14:55:34,175 INFO sqlalchemy.engine.base.Engine.0x...d20c ()
2009-06-15 14:55:34,176 INFO sqlalchemy.engine.base.Engine.0x...d20c COMMIT
2009-06-15 14:55:34,177 INFO sqlalchemy.engine.base.Engine.0x...d20c INSERT
INTO mytable (number) VALUES (?)
2009-06-15 14:55:34,177 INFO sqlalchemy.engine.base.Engine.0x...d20c [[98], 
[94], [7], [1], [79], [77], [51], [28], [85], [26], [34], [68], [15], [43], 
[52], [97], [64], [82], [11], [71], [27], [75], [60], [85], [42], [40], 
[76], [12], [81], [69]]
2009-06-15 14:55:34,178 INFO sqlalchemy.engine.base.Engine.0x...d20c COMMIT
2009-06-15 14:55:34,180 INFO sqlalchemy.engine.base.Engine.0x...d20c SELECT
avg(mytable.number) AS avg_1, np_var(mytable.number) AS np_var_1 FROM mytable
2009-06-15 14:55:34,180 INFO sqlalchemy.engine.base.Engine.0x...d20c []
RESULT ROW: (55.0, 831.0)

Note that I didn't use SQLAlchemy's ORM (just the sql expression part of SQLAlchemy was used) but you could use ORM just as well. 请注意,我没有使用SQLAlchemy的ORM(只使用了SQLAlchemy的sql表达式部分),但您也可以使用ORM。

at first you have to import func from sqlalchemy 首先你必须从sqlalchemy导入func

you can write 你可以写

func.avg('fieldname') func.avg( '字段名')

or func.avg('fieldname').label('user_deined') 或func.avg('fieldname')。label('user_deined')

or you can go thru for mre information 或者你可以通过mre信息

http://www.sqlalchemy.org/docs/05/ormtutorial.html#using-subqueries http://www.sqlalchemy.org/docs/05/ormtutorial.html#using-subqueries

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用Join和Aggregate编写SQLAlchemy查询? - How can I write an SQLAlchemy Query with a Join and an Aggregate? 如何在不使用堆栈或队列的情况下编写自己的等效于Python的推入和弹出函数的Python? - How can I write my own Python equivalent of stack push and pop functions without using a stack or queue? 如何缓存/记忆我的SQLAlchemy函数? - How can I cache/memoize my SQLAlchemy functions? 如何在 sqlalchemy 中编写自己的方言以适应 HTTP API? - How to write my own dialect in sqlalchemy to adapt HTTP API? 我如何在 django 中编写自己的自定义表单小部件 - How can i write my own custom form widget in django 如何在Python中编写自己的OrderedDict类? - How can I write my own OrderedDict class in Python? 如何在Django中编写自己的装饰器? - How can I write my own decorator in Django? 如何在django中编写自己的权限 - How can I write my own permissions in django Using SQLalchemy ORM for Python In my REST api, how can I aggregate resources to the hour to the day? - Using SQLalchemy ORM for Python In my REST api, how can I aggregate resources to the hour to the day? 如何在SQLAlchemy中编写此SQL查询? - How can I write this SQL query in SQLAlchemy?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM