我有一个 django-orm 数据库,其中填充了电子表格中收集的数据。我正在尝试编写一个 diff 函数来根据电子表格的内容检查数据库的当前状态。我使用路由器从电子表格中加载数据,将其放入临时的 sqlite 数据库(“默认”数据库是 postgres),这是我的路由器:
reference_models = ['Stimulus'] # these values are fixed
load_models = ['Response', 'Participant'] # these values vary per spreadsheet
class TestRouter(object):
def db_for_read(self, model, **hints):
if model._meta.object_name in reference_models:
return 'default'
else:
assert model._meta.object_name in load_models
return 'test'
def db_for_write(self, model, **hints):
assert model._meta.object_name not in reference_models
return 'test'
def allow_relation(self, obj1, obj2, **hints):
return True
def allow_syncdb(self, db, model):
if db == "test":
return True
return None
从我的差异脚本测试:
print("---> there are", Response.objects.all().using("default").count(), "original Response objects")
print(Response.objects.all().using("default").select_related("participant"))
print("---> there are", Response.objects.all().count(), "temporary Response objects")
print(Response.objects.all())
这个的输出是:
---> there are 137709 original Response objects
[ ## LOTS OF OBJECTS ##, '...(remaining elements truncated)...']
---> there are 1680 temporary Response objects
[]
.count()
如果方法找到 1680 个对象,为什么最后的查询是空的?
编辑这是一些额外的诊断信息(from IPython import embed
用于在脚本运行时查看脚本的状态):
In [16]: print Response.objects.all().query
SELECT "data_response"."id", "data_response"."modified", "data_response"."created",
"data_response"."stimulus_id", "data_response"."participant_id", "data_response"."full_response",
"data_response"."full_response_orthography" FROM "data_response" INNER JOIN "data_stimulus" ON
("data_response"."stimulus_id" = "data_stimulus"."id") INNER JOIN "data_participant" ON
("data_response"."participant_id" = "data_participant"."id") ORDER BY "data_stimulus"."task" ASC,
"data_stimulus"."number" ASC, "data_participant"."code" ASC
我想问题是 Stimulus 对象是一个外键,路由器很困惑从哪里读取。但是,我可以在 ipython 控制台中通过 id 提取一个 Response 对象,然后将其 Stimulus 作为常规属性(r = Response.objects.get(id=123)
then s = r.stimulus
)。
另一个编辑我已经使用以下方法破解了一个功能但不令人满意的解决方案:
responses = []
for response in Response.objects.raw("""select * from data_response"""):
responses.append(response)
我不知道为什么这有效而Response.objects.all()
无效。