3

別のソースから提供されたデータベースを使用する必要がある Django アプリケーションがあります。 スキーマを変更できません。以下はすべて inspectdb によって生成されたものです。

class Family(models.Model):
    persistanceid = models.BigIntegerField(primary_key=True)

class Spouseref(models.Model):
    persistanceid = models.BigIntegerField(primary_key=True)

class Family_spouseref(models.Model):
    family_persistanceid = models.ForeignKey(Family, db_column='family_persistanceid')
    wiferefs_persistanceid = models.ForeignKey(Spouseref, unique=True, null=True, db_column='wiferefs_persistanceid', blank=True, related_name='wiferefs')
    husbandrefs_persistanceid = models.ForeignKey(Spouseref, unique=True, null=True, db_column='husbandrefs_persistanceid', blank=True, related_name='husbandrefs')
    childrefs_persistanceid = models.ForeignKey(Spouseref, unique=True, null=True, db_column='childrefs_persistanceid', blank=True, related_name='childrefs')

マッピング テーブル Family_spouseref には Spouseref への複数の外部キーがあるため、ManyToManyField は Family の下では機能しません。このスキーマを考えると、次のようなことを達成するための最も効率的な方法は何ですか?

fam = Family.objects.get(persistanceid=id)
husbands = fam.husbands.all()
wives = fam.wives.all()
children = fam.children.all()

アップデート:

リクエストに応じて...次の関数は、上記のファミリ モデル内に追加しようとしたものです。

私は生のSQLを次のように試しました:

    def husbands(self):
        return Spouseref.objects.raw ('SELECT * FROM spouseref WHERE spouseref.persistanceid IN (SELECT husbandrefs_persistanceid FROM family_spouseref WHERE family_persistanceid=%s);', [self.persistanceid])

どちらが機能しますが、生の SQL が本当に最善の方法でしょうか? この方法では、多くの通常のオブジェクト メソッドを失うようです。

ORM で試してみたところ、Family_spouseref テーブルに列 ID があると考えたがっていましたが、明らかにそうではありませんでした。

Family_spouseref.objects.get(family_persistanceid=self.persistanceid)

プロデュース:

[DEBUG] django.db.backends: (0.001) SELECT "family_spouseref"."id", "family_spouseref"."family_persistanceid", "family_spouseref"."wiferefs_persistanceid", "family_spouseref"."husbandrefs_persistanceid", "family_spouseref"."childrefs_persistanceid" FROM "family_spouseref" WHERE "family_spouseref"."family_persistanceid" = 45036  LIMIT 21; args=(45036,)
DatabaseError: column family_spouseref.id does not exist
LINE 1: SELECT "family_spouseref"."id", "family_spouseref"."family_p...

私も試しました:

Family_spouseref.objects.get(Q(family_persistanceid=self.persistanceid) | Q(husbandrefs_persistanceid__isnull=False))

これは同じ ID エラーを生成しましたが、FK 関係に従おうとしました:

[DEBUG] django.db.backends: (0.000) SELECT "family_spouseref"."id", "family_spouseref"."family_persistanceid", "family_spouseref"."wiferefs_persistanceid", "family_spouseref"."husbandrefs_persistanceid", "family_spouseref"."childrefs_persistanceid" FROM "family_spouseref" LEFT OUTER JOIN "spouseref" ON ("family_spouseref"."husbandrefs_persistanceid" = "spouseref"."persistanceid") WHERE ("family_spouseref"."family_persistanceid" = 45036  OR "spouseref"."persistanceid" IS NOT NULL) LIMIT 21; args=(45036,)
DatabaseError: column family_spouseref.id does not exist
LINE 1: SELECT "family_spouseref"."id", "family_spouseref"."family_p...

同じ (悪い) ステートメント (8 回) と生の SQL を 2 回呼び出す頻度をデバッグで確認するのも恐ろしいことです。(それでも2回!)

ORMを完全に無視して生のSQLを実行するのではなく、これらのテーブルをトラバースするための公式のDjangoの方法を本当に知りたいです。ありがとう。

4

1 に答える 1

2

あなたが得ているエラーは、引数として宣言された "primary_key=True" がフィールドにない場合、Django がデフォルトで "id" フィールドを主キーとして設定したためです (たとえば、Family モデルでそれを行いました)。したがって、モデル オブジェクトを取得しようとすると、常に次のようなエラーが発生します。

DatabaseError: column family_spouseref.id does not exist

まず、そのモデルに主キーを与えます。私はそれが1つあるに違いない。いいえの場合は、これを読みたいだけかもしれません。さて、効率の問題については、次のことができます。

def husbands(self):
    husbandrefs_for_family = Family_spouseref.objects.filter(
        family_persistanceid=self.persistanceid,
    ).values_list('husbandrefs_persistanceid',flat=True)

    return Spouseref.objects.filter(
        persistanceid__in=husbandrefs_for_family,
    )

2 つのクエリを実行しているように見えますが、Django は 1 つだけを作成していることがわかります (これは、SQL で行ったようなサブクエリを使用したクエリです)。

サブクエリのvalues_list一部は、必要なテーブルの列だけを取得するために使用されます。私はselect husbandrefs_persistanceidあなたが望む SLQ ステートメントの一部です。

それが役に立てば幸い!

于 2012-06-10T01:10:04.777 に答える