スプレッドシートで収集されたデータが取り込まれた 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
私のdiffスクリプトからテストします:
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()
ません。