在flask-SQLAlchemy中保存和恢复查询

时间:2013-12-16 22:22:15

标签: python sqlite serialization sqlalchemy flask-sqlalchemy

我正在根据用户完成的搜索构建查询,但只提取切片。在接下来的10分钟内,用户可以请求下一个slice \ page,因此我想存储查询并在用户想要下一个切片时恢复它。理想情况下,我不想从头开始构建查询,而是将其恢复到原来的状态,然后抓住下一个切片。

我遇到过 - > http://docs.sqlalchemy.org/en/rel_0_8/core/serializer.html似乎是针对此用例的,但是当我尝试在查询中运行它时,我遇到了问题。

  

lib / python2.7 / copy_reg.py“,第70行,在_reduce_ex中       引发TypeError,“不能pickle%s对象”%base。 name   TypeError:无法pickle函数对象

我怀疑是由于使用了查询对象中的函数flask-SQLAlchemy但是我不确定问题究竟在哪里。

您是否有关于如何继续前进的提示或建议?或者可能是另一种方法。

这是破坏它的代码。

from flask.ext.sqlalchemy import SQLAlchemy
from sqlalchemy.orm import relationship
from sqlalchemy.ext.serializer import loads, dumps
from sqlalchemy import Table, Column, Integer, ForeignKey

db = SQLAlchemy(app)


class Blink(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    uploaded_sd = db.Column(db.Boolean, default=False, index=True)
    blink_metadata = relationship("BlinkMetadata", remote_side='BlinkMetadata.blink_id',
                                  primaryjoin='blink.c.id==blink_metadata.c.blink_id')


class BlinkMetadata(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    blink_id = db.Column(db.Integer, ForeignKey('blink.id'), index=True)
    metadata_id = db.Column(db.Integer, index=True)
    metadata_type_id = db.Column(db.Integer)
    created_date = db.Column(db.DateTime)
    last_updated = db.Column(db.DateTime)
    blink = relationship("Blink", remote_side='Blink.id',
                         primaryjoin=('blink_metadata.c.blink_id==blink.c.id'))

def make_sample_query():
    q = db.session.query(Blink).filter(Blink.uploaded_sd == 1)

    activity_filter = (
        (BlinkMetadata.metadata_id == 1) &
        (BlinkMetadata.metadata_type_id == 1)
    )

    q = q.join(Blink.blink_metadata, aliased=True).filter(activity_filter)

    serialised_query = dumps(q)

1 个答案:

答案 0 :(得分:0)

为了解决这个问题,我采取了不同的策略。相反,我将查询构建为字符串(作为ORM字符串,而不是SQL字符串)。我然后存储查询,并根据需要使用 eval()恢复和执行。

我将查询字符串传递给 page_query(),然后根据需要使用 next_page()调用页面。

def page_query(query_string):

  transaction_id = create_query_transaction(0, BLINKS_PAGE_SIZE, query_string)
  return transaction_id


def next_page(transaction_id):

    transaction = BlinkQueryTransaction.query.get(transaction_id)

    query = eval(transaction.sql)
    query = query.slice(transaction.latest_offset, transaction.page_size)

    transaction.latest_offset = transaction.latest_offset + transaction.page_size
    db.session.commit()

    return query


def create_query_transaction(latest_offset, page_size, query):

    bqt = BlinkQueryTransaction(latest_offset=latest_offset, page_size=page_size, sql=query)
    bqt = save_to_db(bqt)

    return bqt.id