Django“不能适配类型”错误使用多数据库(PostgreSQL 8.4和sqlite3) [英] Django "can't adapt type" error using mutliple databases (Postgresql 8.4 and sqlite3)

查看:105
本文介绍了Django“不能适配类型”错误使用多数据库(PostgreSQL 8.4和sqlite3)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简短描述

使用本地(sqlite3)数据库我可以保存和提取信息,但是当使用我的生产服务器(postgresql 8.4在不同的机器上)Django抛出无法修改类型错误。有人可以帮助我指出一个很好的方向开始调试这个?

Short Description
Using a local (sqlite3) database I can save and extract information, however when using my production sever (postgresql 8.4 on a different machine) Django throws a "can't adapt type" error. Can someone help point me in a good direction to start debugging this?

背景

python项目使用Django 1.3将ORM导入多个数据库(生产和调试)。多数据库连接在所有情况下都工作,但是这一个。在搜索SO和Google时,大多数这些错误是通过重新运行syncdb来修复的。我已经在我的生产和调试服务器上这样做,仍然得到相同的错误。看了模型,访问器和mutator后,我看不到这个函数有什么不同。我包括可疑函数,我的模型和错误消息。任何帮助将不胜感激。我很高兴发布任何其他,非敏感的信息需要。

Background
The python project uses Django 1.3 for an ORM to multiple databases (production and debug). The multiple database connection works on in all cases but this one. In searching SO and Google, most of these errors were fixed by re-running syncdb. I have done this on both my production and debug server and still get the same error. After looking at the models, accessors and mutators I cannot see what is different about this function. I have included the suspect functions, my model, and error message. Any help would be greatly appreciated. I'll be glad to post any other, non sensitive, information needed.

系统信息

* Postgresql 8.4 - Ubuntu服务器

* Django项目用户) - Windows XP(如图所示),Mac OSX,Windows 7(64位)

* Python 2.7.1

* Psycopg2

* Django 1.3

System Information
* Postgresql 8.4 - Ubuntu Server
* Django Project (Client / Users)- Windows XP (as shown), Mac OSX, Windows 7 (64bit)
* Python 2.7.1
* Psycopg2
* Django 1.3

Models.py

from django.db import models

# Create your models here.
class Card_Test(models.Model):
    name = models.TextField(max_length=100)
    description = models.TextField(max_length=200)
    units = models.TextField(max_length=500)
    result_tags = models.TextField(max_length=500)

    def __unicode__(self):
        return self.name

class Status_Type(models.Model):
    status = models.CharField(max_length=25)

    def __unicode__(self):
        return self.status

class Card_Test_List(models.Model):
    card_id = models.ForeignKey('Card')
    card_test_id = models.ForeignKey('Card_Test')
    card_test_sub_id = models.PositiveIntegerField()
    status       = models.ForeignKey('Status_Type')
    result       = models.TextField()
    ran_on       = models.DateField()
    ran_by       = models.CharField(max_length=50)
    run_number   = models.PositiveIntegerField()

    def __unicode__(self):
        return self.card_test_id.__unicode__()

class Card_Type(models.Model):
    card_type = models.CharField(max_length=25)

    def __unicode__(self):
        return self.card_type

class Card(models.Model):
    serial_number = models.CharField(max_length=25)
    card_type = models.ForeignKey('Card_Type')
    status = models.ForeignKey('Status_Type')
    card_tests = models.ManyToManyField('Card_Test', through='Card_Test_List')

    def __unicode__(self):
        return self.serial_number

    def print_all_cards(self):
        print Card.objects.all()

class System_Test_Type(models.Model):
    test_type = models.CharField(max_length=25)

    def __unicode__(self):
        return self.test_type

class System_Test(models.Model):
    name        = models.CharField(max_length=100)
    description = models.CharField(max_length=100)
    units       = models.CharField(max_length=100)

    def __unicode__(self):
        return self.name


class System_Test_List(models.Model):
    chassis_id = models.ForeignKey('Chassis')
    system_test_id = models.ForeignKey('System_Test') 
    result     = models.CharField(max_length=25)
    ran_on     = models.DateField()
    ran_by     = models.CharField(max_length=50)
    test_type  = models.ForeignKey('System_Test_Type')

    def __unicode__(self):
        return self.system_test_id.__unicode__()

class Chassis(models.Model):
    serial_number = models.CharField(max_length=25)
    slot_311 = models.ForeignKey(Card, related_name='slot1_card')
    slot_175 = models.ForeignKey(Card, related_name='slot2_card')
    slot_345 = models.ForeignKey(Card, related_name='slot3_card')
    slot_346 = models.ForeignKey(Card, related_name='slot4_card')
    slot_344 = models.ForeignKey(Card, related_name='slot5_card')
    slot_178 = models.ForeignKey(Card, related_name='slot6_card')
    backplane_serial = models.TextField(max_length=25)
    site_location    = models.TextField(max_length=25)
    status_env_70c  = models.ForeignKey('Status_Type', related_name='70C')
    status_env_10c  = models.ForeignKey('Status_Type', related_name='10C')
    status_assembly = models.ForeignKey('Status_Type', related_name='assembly')
    status_final    = models.ForeignKey('Status_Type', related_name='final')
    system_test = models.ManyToManyField(System_Test, through='System_Test_List')

    def __unicode__(self):
        return self.serial_number

Settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'production',                    # Or path to database file if using sqlite3.
        'USER': 'tester',                      # Not used with sqlite3.
        'PASSWORD': 'xxxxxx',                  # Not used with sqlite3.
        'HOST': '10.10.100.30',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
                  },
    'debug': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': curdir + '/mux_db',
        'USER': '',                     
        'PASSWORD': '',                 
        'HOST': '',                     
        'PORT': '', 
            }
}

Accssors / Mutators

适用于调试和生产数据库

Works on both debug and production database

def get_chassis_by_sn(chassis_id):
    try:
        return Chassis.objects.using(get_database()).filter(serial_number__iexact=chassis_id)
    except Chassis.DoesNotExist:
        return []

仅适用于调试数据库。如果在上失败,则查看行上的内嵌注释

Only works on debug database. See inline comments on the line if fails on

def modify_chassis_sn(current, new):
    #chassis = Chassis.objects.using(get_database()).filter(serial_number__iexact=current)
    try:
        chassis = Chassis.objects.using(get_database()).filter(serial_number__iexact=current)
    except Chassis.DoesNotExist:
        err.Handle_MUX_Error('Unknown Chassis / Serial Number')
        return False
    chassis = chassis[0] # <--- Fails here

    # Update the serial number
    chassis.serial_number = new
    chassis.save(using=get_database())
    return True

def modify_chassis_record(sn, slots=None, bp_sn=None, site_loc=None ):

    #chassis = Chassis.objects.using(get_database()).filter(serial_number__iexact=sn)

    try:
        c = Chassis.objects.using(get_database()).filter(serial_number__iexact=sn)
        print len(c)
    except Chassis.DoesNotExist:
        err.Handle_MUX_Error('Unknown Chassis / Serial Number')
        return False
    chassis = c[0]  # <--- Fails here

    # Update the List of Cards (if provided)
    if slots != None:
        if len(slots) != 6:
            err.Handle_MUX_Error('You must enter 6 serial numbers!')
            return False

        index = 0
        db_slots = [None]*6
        for slot in slots:
            s = get_card_by_sn(slot)

            if len(s) == 0:
                err.Handle_MUX_Error('Slot ' + str(index) + ' serial number does not exist!')
                return False

            db_slots[index] = s[0]
            index +=1

        chassis.slot_311 = db_slots[0]
        chassis.slot_175 = db_slots[1]
        chassis.slot_345 = db_slots[2]
        chassis.slot_346 = db_slots[3]
        chassis.slot_344 = db_slots[4]
        chassis.slot_178 = db_slots[5]

    # Update the Backplane Serial Number (if provided)
    if bp_sn != None:
        chassis.backplane_serial = bp_sn

    # Update the site Location (if provided)
    if site_loc != None:
        chassis.site_location = site_loc

    # Save all changes to the chassis
    print chassis
    chassis.save(using=get_database())
    return True

错误讯息

Traceback (most recent call last):
  File "C:\Documents and Settings\User\Desktop\Python\exe\wx_gui\Assembly_Panel.py", line 276, in SaveChassis
    mux_api.modify_chassis.run(active_chassis, new_chassis_id, bp_sn=backplane_sn)
  File "C:\Documents and Settings\User\Desktop\Python\exe\api_rehabilitation_suite\modify_chassis.py", line 10, in run
    modify_status = db.modify_chassis_record(sn, slots=slots, bp_sn=bp_sn, site_loc=site_loc )
  File "C:\Documents and Settings\User\Desktop\Python\mux_test_data\db_driver.py", line 136, in modify_chassis_record
    print len(c)
  File "C:\Python27\lib\site-packages\django\db\models\query.py", line 82, in __len__
    self._result_cache = list(self.iterator())
  File "C:\Python27\lib\site-packages\django\db\models\query.py", line 273, in iterator
    for row in compiler.results_iter():
  File "C:\Python27\lib\site-packages\django\db\models\sql\compiler.py", line 680, in results_iter
    for rows in self.execute_sql(MULTI):
  File "C:\Python27\lib\site-packages\django\db\models\sql\compiler.py", line 735, in execute_sql
    cursor.execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\backends\util.py", line 34, in execute
    return self.cursor.execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\backends\postgresql_psycopg2\base.py", line 44, in execute
    return self.cursor.execute(query, args)
django.db.utils.DatabaseError: can't adapt type 'Chassis'


推荐答案

结果是sqlite3忽略和或尝试将值转换为字符串时使用它在一个Django过滤器。从GUI我传递实际的机箱对象而不是序列号。 Postgresql在尝试使用机箱对象作为序列号时抛出错误,而sqlite3忽略它并将其强制转换为字符串(在Django中将其定义为序列号)。

Turns out that sqlite3 ignores and or tries to convert a value to a string when using it in a Django filter. From the GUI I was passing in the actual chassis object rather than the serial number. Postgresql threw the error when trying to use a Chassis object as a serial number while sqlite3 ignored it and cast it as a string (which I defined in Django as the serial number).

我希望这个发现在尝试调试此类错误时可能会帮助别人。

I hope this discovery might help someone else when trying to debug this type of error.

感谢所有谁看了这个。

这篇关于Django“不能适配类型”错误使用多数据库(PostgreSQL 8.4和sqlite3)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆