Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django与tastypie如何刷新queryset?_Python_Django_Django Models_Tastypie - Fatal编程技术网

Python Django与tastypie如何刷新queryset?

Python Django与tastypie如何刷新queryset?,python,django,django-models,tastypie,Python,Django,Django Models,Tastypie,我的数据库中的一些表是从后台不断运行的一些后台python脚本(进行数据挖掘)中更新的。Django很难知道数据是在Django之外更新的,并且总是显示旧数据。经过长时间的研究,大多数在线禁用缓存的方法对我来说都不起作用,但这种解决方法非常有效: from django.db import connection connection.close() 这仍然不是一个完美的解决方案,但在Django看来确实有效。如果你知道如何解决这个问题,请在这里发表评论。但是,REST也可以访问数据。在tast

我的数据库中的一些表是从后台不断运行的一些后台python脚本(进行数据挖掘)中更新的。Django很难知道数据是在Django之外更新的,并且总是显示旧数据。经过长时间的研究,大多数在线禁用缓存的方法对我来说都不起作用,但这种解决方法非常有效:

from django.db import connection
connection.close()
这仍然不是一个完美的解决方案,但在Django看来确实有效。如果你知道如何解决这个问题,请在这里发表评论。但是,REST也可以访问数据。在tastype中,资源仍然没有更新

JSON结构总是返回过时的时间戳,我可以看到数据库中的最新值是不同的。我已经尝试了以下方法,但没有成功

from tastypie.cache import NoCache
cache = NoCache()
现在刷新它的唯一方法是手动重新启动uwsgi服务,这显然不是一个解决方案。这个问题快把我逼疯了。如有任何意见,将不胜感激。多谢各位


更新

我简化了代码和模型,只包含timestamp列。这是完整的代码和日志

Tastypie的资源.py

from lp.models import LatestPrices
from tastypie.resources import ModelResource
from tastypie.serializers import Serializer
from django.db import connection

class LpResource(ModelResource):
    class Meta:

        # forces Django to make a new connection, fixes OperationalError: (2006, 'MySQL server has gone away') after a long time with no access
        connection.close() 

        queryset = LatestPrices.objects.all()

        include_resource_uri = False
        resource_name = 'lp'
        allowed_methods = ['get']
        excludes = ['slug']
        serializer = Serializer(formats=['json'])
        connection.close()
型号.py

from django.db import models

class LatestPrices(models.Model):
    id = models.AutoField(primary_key=True)
    slug = models.SlugField(unique=True)

    # timestamp is updated every 10 seconds
    timestamp = models.DateTimeField(null=True, blank=True)

    # Removed all other columns for debugging.

    # The data to show in admin
    def __unicode__(self):
        return str(self.timestamp)

    class Meta:
        db_table = 'latest_prices'
Django之外的DB injector脚本

while True:
    try:
        # Get date & time
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        logger.info("------" + timestamp)

        # Inject to local database
        logger.debug("Injecting...")
        con = None
        con = db.connect('localhost', 'user', 'pw', 'tablename')
        con.autocommit(True)
        cursor = con.cursor(MySQLdb.cursors.DictCursor)
        update_query = "UPDATE latest_prices SET slug='latest', timestamp='" + timestamp \
                             + "' WHERE id=1"
        rows_affected = cursor.execute(update_query)
        con.commit()
        if rows_affected != 1:
            logger.critical("Couldn't inject! Rows affected: " + str(rows_affected))
            cursor.close()
            time.sleep(WAIT_TIME)
            continue

        cursor.close()

    except Exception as e:
        # Code removed. Email admin the error string...
        pass
    finally:    
        pass

    time.sleep(WAIT_TIME)
mysql.log

          124 Query UPDATE latest_prices SET slug='latest', timestamp='2013-04-04 18:38:16' WHERE id=1
          124 Query commit
130404 18:38:26   125 Connect   dev@localhost on gs
          125 Query set autocommit=0
          125 Query set autocommit=1
          124 Quit  
          125 Query UPDATE latest_prices SET slug='latest', timestamp='2013-04-04 18:38:26' WHERE id=1
          125 Query commit
130404 18:38:36   126 Connect   dev@localhost on gs
          126 Query set autocommit=0
          126 Query set autocommit=1
          125 Quit  
          126 Query UPDATE latest_prices SET slug='latest', timestamp='2013-04-04 18:38:36' WHERE id=1
          126 Query commit
130404 18:38:46   127 Connect   dev@localhost on gs
          127 Query set autocommit=0
          127 Query set autocommit=1
          126 Quit  
          127 Query UPDATE latest_prices SET slug='latest', timestamp='2013-04-04 18:38:46' WHERE id=1
          127 Query commit

# Click the browser refresh button one time here
130404 18:38:53    73 Query SELECT `latest_prices`.`id`, `latest_prices`.`slug`, `latest_prices`.`timestamp` FROM `latest_prices` WHERE (`latest_prices`.`id` = 1  AND `latest_prices`.`id` = 1 )

130404 18:38:56   128 Connect   dev@localhost on gs
          128 Query set autocommit=0
          128 Query set autocommit=1
          127 Quit  
          128 Query UPDATE latest_prices SET slug='latest', timestamp='2013-04-04 18:38:56' WHERE id=1
          128 Query commit

# Click the browser refresh button a few times here
130404 18:38:58    70 Query SELECT `latest_prices`.`id`, `latest_prices`.`slug`, `latest_prices`.`timestamp` FROM `latest_prices` WHERE (`latest_prices`.`id` = 1  AND `latest_prices`.`id` = 1 )
130404 18:39:02    70 Query SELECT `latest_prices`.`id`, `latest_prices`.`slug`, `latest_prices`.`timestamp` FROM `latest_prices` WHERE (`latest_prices`.`id` = 1  AND `latest_prices`.`id` = 1 )
130404 18:39:04    73 Query SELECT `latest_prices`.`id`, `latest_prices`.`slug`, `latest_prices`.`timestamp` FROM `latest_prices` WHERE (`latest_prices`.`id` = 1  AND `latest_prices`.`id` = 1 )

130404 18:39:06   129 Connect   dev@localhost on gs
          129 Query set autocommit=0
          129 Query set autocommit=1
          128 Quit  
          129 Query UPDATE latest_prices SET slug='latest', timestamp='2013-04-04 18:39:06' WHERE id=1
          129 Query commit
130404 18:39:16   130 Connect   dev@localhost on gs
          130 Query set autocommit=0
          130 Query set autocommit=1
          130 Query UPDATE latest_prices SET slug='latest', timestamp='2013-04-04 18:39:16' WHERE id=1
          129 Quit  
          130 Query commit
{"id": 1, "timestamp": "2013-04-04T18:29:45"}
浏览器输出(始终相同)

HTTP头文件

Cache-Control →no-cache
Connection →keep-alive
Content-Type →application/json
Date →Fri, 05 Apr 2013 00:27:48 GMT
Server →nginx
Transfer-Encoding →
Transfer-Encoding
The form of encoding used to safely transfer the entity to the user. Currently defined methods are: chunked, compress, deflate, gzip, identity.

chunked
Vary →Accept
我还在注入器脚本中添加了一个显式提交。它在mysql.log中表示提交,与我使用的现有“set autocommit=1”没有太大区别


现在我正在查看mysql.log,每次我点击浏览器的刷新按钮,我都会看到Django发送的新SELECT语句。但这些物品仍然很旧。我不明白,为什么?

Django将在查询集中缓存结果,但不会在不相关的查询集中缓存结果

以下代码将导致两个数据库查询:

list(SomeTable.objects.all())  # First db query.
list(SomeTable.objects.all())  # Second db query unrelated to first.
症状和您的
connection.close()
解决方案与MySQL事务问题一致。每个查询上的新连接将导致不同的事务

似乎事务正在Django代码中启动,但从未提交或回滚。当事务开始时,该事务中的进一步读/写操作将只看到事务开始时的数据库状态,以及在该事务中进行的更新。如果另一个进程启动会话(例如数据挖掘脚本)并插入数据,Django事务在关闭现有事务之前不会看到该会话


如果没有看到您的代码,就不可能知道为什么会有一个已启动但未完成的事务。要验证此假设,请打开MySQL查询日志并检查其内容。您应该会看到一个
start transaction
查询,但没有相应的
commit
rollback

将“事务隔离=读取提交”添加到my.cnf。这里有更多详细信息:

Django确实会在queryset中缓存结果,但如果您实例化一个新的queryset数据库,它将再次被命中,并且不会涉及缓存。你在使用什么数据库?可能是因为您的数据挖掘脚本没有提交内容而导致的问题?如何实例化新的查询集?我使用的是MySQL,我可以使用不同的MySQL客户端查看数据,因此我确信数据已经提交并且存在。qs=SomeTable.objects.all()实例化一个新的queryset。在一个shell中尝试,你应该真正看到你的对象在DB中的样子。不,Django真的在缓存东西。>>list1=list(LatestPrices.objects.all())>>>>list1[0]。时间戳datetime.datetime(2013,4,4,14,40,36)>>>#实际时间戳应为2013-04-04 14:43:02>>>>>>>list2=list(LatestPrices.objects.all())>>list2[0]。时间戳datetime.datetime(2013,4,4,14,40,36)>>>#实际时间戳现在是2013-04-04 14:45:50默认情况下,Django将只在查询集中缓存结果,正如Ponytech所评论的那样。在使用mysql命令行客户端时,您确定数据库中存在记录吗(例如,数据挖掘脚本以外的内容)?也许您的数据挖掘脚本正在未提交的sql事务中编写?只是用运行的代码更新了问题。显式提交仍然存在问题(我使用的是自动提交)。connection.close()强制Django转储其缓存。数据在数据库中,正如在本地和远程MySQL客户端中所显示的那样。@Terry您能指出Django源代码,其中
connection.close()
强制缓存转储吗?[提示:没有缓存]。您已经证明数据在数据库中,但在Django打开的事务中不可见。我无法在mysql日志中查看会话70的完整会话,以查看查询之前的内容。使用mysql客户端试验事务行为。执行
启动事务
,然后从另一个shell运行注入器脚本,然后从事务中选择
。你看到更新的时间戳了吗?你完全正确!你的评论让我做了更多的研究,并让我找到了尼克·克雷格·伍德的答案。我基本上只是在my.cnf中添加了“transaction isolation=READ-COMMITTED”,现在Django可以神奇地看到这些变化了!非常感谢。