2

目前我的数据库中有一个表,其中包含 id、name (str) 和 data (int) 列。有一个 html 单选按钮表单,其中选择一个按钮会将 1 添加到数据库中的相应条目:

length_table=session.query(func.count(Item.id)).scalar()
randoms=random.sample(range(length_table),2)
item1=session.query(Item).filter_by(id=randoms[0]+1).one()
item2=session.query(Item).filter_by(id=randoms[1]+1).one()

if request.POST.get('myradiobutton') == "left":
    item1.data+=1
    return HTTPFound(location=request.route_url('sorting'))

if request.POST.get('myradiobutton') == "right":
    item2.data+=1
    return HTTPFound(location=request.route_url('sorting'))

这可行,但它有一些伪劣行为(有时会添加到正确的项目,有时会添加到错误的项目)。因为我使用的是应该处理提交的pyramid_tm 。SQL日志给了我:

SELECT rowid, *  FROM items ORDER BY rowid; 
SELECT name, sql FROM sqlite_master WHERE type='table' ;
PRAGMA TABLE_INFO(items);
SELECT name, sql FROM sqlite_master WHERE type='index' 

没有更新语句对我来说很奇怪。如果没有发布,如何更新数据库?我相信更新应该发生在 transaction.commit() 行上。

这是表定义:

class Item(Base):
    __tablename__ = 'items'
    id = Column(Integer, primary_key=True)
    name = Column(Text, unique=True)
    data = Column(Integer)

    def __init__(self, name, data):
        self.name = name
        self.data = data

这就是创建引擎的地方:

def main(argv=sys.argv):
    if len(argv) != 2:
        usage(argv)
    config_uri = argv[1]
    setup_logging(config_uri)
    settings = get_appsettings(config_uri)
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)
    Base.metadata.create_all(engine)
4

2 回答 2

2

我不完全确定您的item1item2来自哪里,但我假设您在发布逻辑之前的某个地方初始化它们,例如:

item1 = DBSession.query(Item).filter(Item.id == passed_value).first()

如果不是,什么是item1item2

无论如何,假设您已经有一个有效的item1对象并想要更新它,并且您正在使用 ZopeTransactionExtension 我最终会做这样的事情:

if request.POST.get('myradiobutton') == "left":
    item1.data+=1
    DBSession.add(item1)
    DBSession.flush()
    return HTTPFound(location=request.route_url('sorting'))
于 2013-10-25T20:29:44.370 回答
0

好的,这就是问题所在。当我第一次调用 item1 和 item2 时,它会使用随机数形式的随机整数随机查询数据库。

但是当它到达该行时item1.data+=1,它会尝试再次随机查询 item1。这意味着无论输出是什么(右或左),它都会再次从数据库中随机选择一个项目来加 1。又名不一致的结果。

为了解决这个问题,我不得不将我的代码分成 GET 和 POST 案例,如下所示。基本上,当页面最初加载时,我在 GET 方法中创建了两个随机“键”。然后我将密钥传递给模板

if request.method == "GET":


        length_table=session.query(func.count(Item.id)).scalar()
        randoms=random.sample(range(1,length_table+1),2)


        results = session.query(Item).filter(Item.id.in_(randoms)).all()


        return {'randoms':randoms,'item1':randoms[0],'item2':randoms[1],'results':results}

然后在模板上,我将这些键值放入用户作为隐藏值提交的表单中

<input type="hidden" name="item1" value=${item1}>
<input type="hidden" name="item2" value=${item2}>

最后,在 POST 部分,我引入了这些值。这意味着它们不会被重新随机化,而是与查询原始项目时使用的键值相同。

if request.method == "POST":

        key1=request.params['item1']
        key2=request.params['item2']
        randoms=[key1,key2]
        results = session.query(Item).filter(Item.id.in_(randoms)).all()
        if output == "left":
            results[0].data=results[0].data+1

            return HTTPFound(location=request.route_url('sorting'))

        if output == "right":
            results[1].data=results[1].data+1
            return HTTPFound(location=request.route_url('sorting'))
于 2013-11-04T09:06:40.467 回答