2013-04-16 11 views
14

basit bir yorum modelinde inşa django yıllardan sorguyu ve Heroku en postgreSQL veritabanı ile aşağıdaki hatayı alıyorum var atmalarını: etrafında Googling sonraheroku, postgreSQL, django, yorumlar, tastypie: Hiçbir operatör, verilen isim ve argüman türü ile eşleşmiyor. Sen açık türünü eklemeniz gerekebilir

DatabaseError: operator does not exist: integer = text LINE 1: 
... INNER JOIN "django_comments" ON ("pi ns_pin"."id" = "django_... 
                 ^
HINT: No operator matches the given name and argument type(s). 
You might need to add explicit type casts. 

bu hata birçok kez ele alınmıştır görünüyor django'da daha önce, ama hala alıyorum (tüm ilgili konular 3-5 yıl önce kapatıldı). Ben django sürüm 1.4 ve en son tastypie yapıyorum kullanıyorum.

sorgu orm filtrelerin altında yapılır ve benim geliştirme veritabanı (Sqlite3) ile mükemmel çalışıyor:

class MyResource(ModelResource):  

    comments = fields.ToManyField('my.api.api.CmntResource', 'comments', full=True, null=True) 

    def build_filters(self, filters=None): 
     if filters is None: 
      filters = {} 

     orm_filters = super(MyResource, self).build_filters(filters) 

     if 'cmnts' in filters: 
      orm_filters['comments__user__id__exact'] = filters['cmnts'] 

class CmntResource(ModelResource): 
    user = fields.ToOneField('my.api.api.UserResource', 'user', full=True) 
    site_id = fields.CharField(attribute = 'site_id') 
    content_object = GenericForeignKeyField({ 
     My: MyResource, 
    }, 'content_object') 
    username = fields.CharField(attribute = 'user__username', null=True) 
    user_id = fields.CharField(attribute = 'user__id', null=True) 

Herkes ham SQL yazmadan bu hatanın dolaşmakta herhangi bir deneyimi var?

+0

Hatada olduğu gibi, bir tamsayı bir metin değeriyle karşılaştırmaya çalışıyorsunuz. Bunu yapmayı bırak ve hata gider. –

+0

Tesadüfen, testin nereye yerleştirildiğinize mümkün olduğunca yakın bir ortamla yapılmasının iyi bir örneği. Ancak, bir çerçeve, bir DBMS'nin karmaşık olduğu kadar farklı bir davranış ve sınırlamaya sahip olduğu kadar karmaşık bir şey olduğunu söylüyor. . – IMSoP

+0

IMSoP, evet, bugün dersi aldım! Bu sorun üzerinde çalışmak için geliştirme DB'yi PostgreSQL'e değiştirdim. – arctelix

cevap

4

IMSoP yanıtı üzerinde Bina: Genel bir yabancı anahtar object_id için bir metin alanı kullanıyorsa ve nesnenin kimlik alanı bir metin alanı değilse, bu django'nun ORM katmanının bir sınırlamasıdır. Django, herhangi bir varsayım yapmak istemiyor ya da nesnenin kimliğini olmayan bir şey olarak kullanmak istemiyor. Bu http://charlesleifer.com/blog/working-around-django-s-orm-to-do-interesting-things-with-gfks/ numaralı telefondan mükemmel bir makale buldum. Bu makalenin yazarı Charles Leifer, bu konudan etkilenen ve bu sorunla başa çıkmak için çok yararlı olacak sorgulama için çok güzel bir çözüm buldu.

Alternatif i aşağıdaki gibi çalışmak benim sorgu başardı i Charles yaptıklarından benzer SQL değiştirmek için bir yol arıyordu

Başlangıçta
if 'cmnts' in filters: 
    comments = Comment.objects.filter(user__id=filters['cmnts'], content_type__name = 'my', site_id=settings.SITE_ID).values_list('object_pk', flat=True) 
    comments = [int(c) for c in comments] 
    orm_filters['pk__in'] = comments 

ama ben gereken tek şey çıkıyor Sorguyu iki bölüme ayırmak ve str (id) 'yi int (id)' ye dönüştürmek.

29

PostgreSQL, "güçlü bir şekilde yazılmıştır" - yani her sorgudaki her değerin, ya açıkça tanımlanmış (örneğin, bir tablodaki bir sütunun türü) ya da dolaylı olarak (örn. WHERE maddesine girilen değerler) belirli bir türü vardır. . = dahil olmak üzere tüm işlevler ve işleçler, belirli türleri kabul etmek olarak tanımlanmalıdır - örneğin, VarChar = VarChar için bir operatör ve için farklı bir tane vardır.

Sizin durumunuzda, açıkça int türünde tanımlanmış bir sütun var, ancak PostgreSQL'in text türü olarak yorumladığı bir değerle karşılaştırıyorsunuz. Öte yandan, SQLite, "zayıf bir şekilde yazılmıştır" şeklindedir - değerler, gerçekleştirilmekte olan işleme en uygun ne olursa olsun, serbest olarak değerlendirilir. Yani, dev SQLite veritabanınızda, '42' = 42 numaralı işlem, yalnızca PostgreSQL'in VarChar = int özel bir tanımına (veya text = int, text PostgreSQL'de sınırsız dizeler için bir tür) ihtiyaç duyacağı bir şekilde hesaplanabilir.

Şimdi, PostgreSQL bazen olacaktır ve türlerin bilinen bir işleçle eşleşmesini sağlamak için değerlerinizi otomatik olarak "yayınlamaya" yardımcı olur, ancak daha sıklıkla, ipucu belirttiği gibi, bunu açıkça yapmanız gerekir. SQL'i kendiniz yazıyorsanız, açık bir harf türü WHERE id = CAST('42' AS INT) (veya WHERE CAST(id AS text) = '42') gibi görünebilir.

Yapmıyorsanız, sorgu oluşturucuya verdiğiniz girdinin, yalnızca rakamlardan oluşan bir dize değil, gerçek bir tam sayı olduğundan emin olmanız gerekir. Bu, fields.CharField yerine fields.IntegerField'u kullanmak kadar basit olduğundan şüpheliyim, ama aslında Django'yu ve hatta Python'u bilmiyorum, o yüzden umarım ki arka plandan alabilirim.

+0

Bilgi için teşekkürler, çok iyi koyar ve hataya ne olduğunu anlıyorum. Sorun, django'nun yorum modeli için gfk'ın object_id için bir metin alanı kullanması ve yorumlanılan nesnenin bir tamsayı alanı kullanmasıdır. Bu yüzden gerçekten de bir arayış, yorum modelini tamsayıya sınırlamadan bununla nasıl başa çıkmalıydı? id en. – arctelix

İlgili konular