简短描述
使用本地(sqlite3)数据库我可以保存和提取信息,但是当使用我的生产服务器(在不同的机器上的postgresql 8.4)时,Django会抛出“无法适应的类型”错误。有人可以帮助我指出一个好的方向来开始调试吗?
背景
python项目使用Django 1.3将ORM用于多个数据库(生产和调试)。多个数据库连接在所有情况下都可以使用,但是这个。在搜索SO和Google时,大多数错误都是通过重新运行syncdb来解决的。我已经在我的生产和调试服务器上完成了这个并且仍然得到相同的错误。在查看模型,访问器和变换器后,我看不出这个函数有什么不同。我已经包含了可疑功能,我的模型和错误消息。任何帮助将不胜感激。我很乐意发布所需的任何其他非敏感信息。
系统信息
* Postgresql 8.4 - Ubuntu Server
* Django项目(客户端/用户) - Windows XP(如图所示),Mac OSX,Windows 7(64位)
* 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
适用于调试和生产数据库
def get_chassis_by_sn(chassis_id):
try:
return Chassis.objects.using(get_database()).filter(serial_number__iexact=chassis_id)
except Chassis.DoesNotExist:
return []
仅适用于调试数据库。如果
失败,请在该行上查看内联注释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'
答案 0 :(得分:4)
事实证明,当在Django过滤器中使用它时,sqlite3会忽略和/或尝试将值转换为字符串。从GUI我传递的是实际的机箱对象而不是序列号。当尝试使用Chassis对象作为序列号时,Postgresql抛出错误,而sqlite3忽略它并将其转换为字符串(我在Django中将其定义为序列号)。
我希望在尝试调试此类错误时,此发现可能会帮助其他人。
感谢所有关注此事的人。