2

DjangoORMを使用してデータベースクエリを処理しています。私は次のdbテーブルを持っています:

  • 資源
  • resource_pool
  • resource_pool_elem
  • 予約

および次のモデル:

class Resource(models.Model):

    name = models.CharField(max_length=200)

class Reservation(models.Model):
    pass

class ResourcePool(models.Model):

    reservation = models.ForeignKey(Reservation, related_name="pools", db_column="reservation")
    resources = models.ManyToManyField(Resource, through="ResourcePoolElem")
    mode = models.IntegerField()

class ResourcePoolElem(models.Model):

    resPool = models.ForeignKey(ResourcePool)
    resource = models.ForeignKey(Resource)

現在、一連の予約で使用されているリソースを照会する必要があります。次のクエリを使用します。

resourcesNames = []
reservations = []
resources = models.Resource.objects.filter(
    name__in=resourcesNames, resPool__reservation__in=reservations).all()

これは、これに似たSQLクエリに一致すると思います。

select *
from resource r join resource_pool rp join resource_pool_elem rpe join reservation reserv 
where r.id = rpe.resource and  
  rpe.pool = rp.id and
  reserv.id = rp.reservation and
  r.name in (resourcesNames[0], ..., resourcesNames[n-1])
  reserv.id in (reservations[0], ..., reservations[n-1])

ここで、このクエリに制限を追加します。各プールには、排他モードのブールフラグがあります。各プールの要求された排他的フラグを含む追加の入力リストがあり、exclusive = trueの場合、排他的フラグが要求された排他的フラグと一致するプールのリソース、または排他的フラグがfalseのプールのリソースのみを照会したいと思います。次のようなコードでPythonを使用してSQLクエリを作成できます。

query = "select * 
    from resource r join resource_pool rp join resource_pool_elem rep
    join reservation reserv 
    where r.id = rpe.resource and  
    rpe.pool = rp.id and 
    reserv.id = rp.reservation and 
    reserv.id in (reservations[0], ..., reservations[n-1]) and ("
for i in resourcesNames[0:len(resourcesNames)]
    if i > 0:
        query += " or "
    query += "r.name = " + resourcesNames[i]
    if (exclusive[i])      
        query += " and p.mode == 0"
query += ")"    

このSQLクエリをDjangoクエリで表現する方法はありますか?

4

2 に答える 2

3

おそらく、 Qオブジェクトでこれを行うことができます。私はあなたの例に頭を包むのにいくつかの問題がありますが、より単純なモデルでそれを見てみましょう。

class Garage(models.Model):
    name     = models.CharField()

class Vehicle(models.Model):
    wheels   = models.IntegerField()
    gears    = models.IntegerField()
    garage   = models.ForeignKey(Garage)

ガレージにすべての「多輪」車両を入れたいとしましょう(たとえば、すべてのオートバイと車、ただし一輪車はありません)が、車の場合は、CVTトランスミッションを備えたものだけが必要です。つまり、ギアは1つだけです。(これがどのように起こったのか、手がかりはありませんが、私に耐えてください...;)以下はあなたにそれを与えるはずです:

from django.db.models import Q
garage = Garage.objects.all()[0]
query = Vehicle.objects.filter(Q(garage=garage))
query = query.filter(Q(wheels=2) | (Q(wheels=4) & Q(gears=1)))

次の利用可能なデータがある場合:

for v in Vehicle.objects.filter(garage=garage):
    print 'Wheels: {}, Gears: {}'.format(v.wheels, v.gears)

Wheels: 1, Gears: 1
Wheels: 2, Gears: 4
Wheels: 2, Gears: 5
Wheels: 4, Gears: 1
Wheels: 4, Gears: 5

クエリを実行すると、次のようになります。

for v in query:
    print 'Wheels: {}, Gears: {}'.format(v.wheels, v.gears)

Wheels: 2, Gears: 4
Wheels: 2, Gears: 5
Wheels: 4, Gears: 1

最後に、それをあなたのケースに適応させるために、あなたは次の線に沿って何かを使うことができるかもしれません:

query = models.Resource.objects.filter(Q(resPool__reservation__in=reservations))
query = query.filter(Q(name__in(resourcesNames))
query = query.filter(Q(resPool__exclusive=True) & Q(resPool__mode=0))
于 2012-10-30T15:18:10.637 に答える
0

たとえば、djangoカーソルを使用してクエリを実行できます

ドキュメントを参照してください: https ://docs.djangoproject.com/en/dev/topics/db/sql/

from django.db import connection

def my_custom_sql(self):
    cursor = connection.cursor()

    cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])

    cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
    row = cursor.fetchone()

    return row
于 2014-10-02T11:41:06.600 に答える