将上下文注释添加到SQLAlchemy查询

时间:2017-10-24 19:29:23

标签: python sqlalchemy

我正在尝试找出一种方法来为SQLAlchemy生成的查询添加注释,以指示其原点。

我知道prefix_with方法,但对它不满意,因为它只会在'SELECT'之后放置前缀,并且我希望我的注释与实际的查询逻辑完全分开。

我偶然发现了一个解决方案,它添加了一个游标执行回调来处理这个详细的here。我的问题是我想添加的评论类型取决于执行查询的位置。

所以,例如,我想做类似以下的事情......

class SomeTableCountMetric(object):

  def __init__(self):
    session = sessionmaker(bind=engine, info={ 'src' : self.__class__.__name__ })

  def get(self):
    return self.session.query(func.count(SomeTable.id)).all()

反过来生成的查询

SELECT COUNT(some_tables.id) FROM some_tables /* { 'src' : SomeTableCountMetric } */

所以,基本上,我希望能够将一些任意值传递给会话或查询对象,然后能够从回调方法中可用的一个参数(连接,游标或上下文)中检索它)。

是否可以这样做,或者是否有其他方法来实现这一点?

此外,是否有任何关于这是否是一个好模式的想法?

1 个答案:

答案 0 :(得分:2)

connection有一个info字典,您可以在其中存储用户定义的数据。您可以将评论信息存储在会话中,并通过after_begin将其传递到关联的connection。此后,您可以在执行之前将注释附加到SQL语句(如另一个answer中所建议的那样)。

# Our session factory, typically is a scoped session
Session = sessionmaker(bind=engine)

# Pass `session` contextual info to `connection`
@event.listens_for(Session, 'after_begin')
def session_on_after_begin(session, transaction, connection):
  if 'src' in session.info:
    connection.info['src'] = session.info['src']


# Append comments to statement
@event.listens_for(engine, "before_cursor_execute", retval=True)
def comment_sql_calls(conn, cursor, statement, parameters, context, executemany):
    if 'src' in conn.info:
        statement = statement + " -- %s" % conn.info.pop('src')
    return statement, parameters


class SomeTableCountMetric(object):

  def __init__(self, session=None):
      if session is None:
          session = Session()
    self.session = session
    self.session.info['src'] = 'some info'

  def get(self):
    return self.session.query(func.count(SomeTable.id)).all()

try:
    qo = SomeTableCountMetric()
    qo.get()
    qo.session.close()
except:
    qo.session.rollback()
相关问题