Найти - Пользователи
Полная версия: SQLAlchemy. relation сработал через раз.
Начало » Базы данных » SQLAlchemy. relation сработал через раз.
1
aaleksander
Доброго времени суток, уважаемые.
Возникла такая проблема.
Заранее извиняюсь за обилие кода, сократил как мог.
Есть таблица “месторождения”, “скважины” и “источники данных”.
У одного месторождения может быть несколько скважин и источников.
Пытаюсь оформить под это дело relations^
#таблица месторождений
field_table = Table('oil_field', metadata,
Column('rn', Integer, primary_key=True),
Column('name', String(50))
)

class Field(object):
def __init__(self, name):
self.name = name
def __repr__(self):
return "<Field ('%d', %s')>" % (self.rn, self.name.encode('utf-8'))

well_table = Table('well', metadata,
Column('rn', Integer, primary_key=True),
Column('prn', Integer, ForeignKey('oil_field.rn')),
Column('well_id', String(20)),
Column('name', String(20)),
Column('latitude', Numeric(15, 6)),
Column('td', Numeric(15, 6)),
Column('datun_elevation', Numeric(15, 6)),
Column('rus_name', String(20))
)

#таблица скважин
class Well(object):
def __init__(self, well_id, name, latitude=0, td = 0, datum=0, rus_name=''):
self.well_id = well_id
self.name = name
self.latitude = latitude
self.td = td
self.datun_elevation = datum
self.rus_name = rus_name
def __repr__(self):
return "<Well: (%d, %s, %s)>" % (self.rn, self.name.encode('utf-8'), self.well_id.encode('utf-8'))

#таблица источников данных
source_table = Table('src', metadata,
Column('rn', Integer, primary_key=True), #чисто, чтобы было
Column('oil_field', Integer, ForeignKey('oil_field.rn')),
Column('src', Integer),
Column('name', String(100))
)

class Source(object):
def __init__(self, oil_field, src, name):
self.oil_field = oil_field
self.src = src
self.name = name

def __repr__(self):
return '<Source: (%s, %s)>' % (self.src, self.name.encode('utf-8'))

#мапим всё
mapper(Well, well_table)
mapper(Source, source_table)

mapper(Field, field_table, properties={
'wells': relation(Well, backref='wells'),
'sourcess': relation(Source, backref='sourcess'),
}
)
Так вот проблемма в том, что когда я получаю скважину и беру из нее wells, то все получается.
А когда пытаюсь получить оттуда sourcess, то мне выдает сообщение:
sqlalchemy.exc.InterfaceError: (InterfaceError) (0, ‘Error while attempting to convert object of type <class \’decimal.Decimal\'> to database-internal numeric type for storage in field . The invalid input object is: Decimal(“33”)') ‘SELECT src.rn AS src_rn, src.oil_field AS src_oil_field, src.src AS src_src, src.name AS src_name \nFROM src \nWHERE ? = src.oil_field’ (Decimal(“33”),)
Для тестов делаю просто:
        f = db.Session().query(db.Field).filter_by(rn=33).first()
print f.wells
print f.sourcess
Уже весь код у Well и Source посимвольно сравнил - одинаково! Не могу понять в чем дело. Помогите кто чем может.
bw
А за РСУБД?

..bw
aaleksander
В смысле, какая СУБД?
firebird.
bw
Да, очепятался.
Не работал с ней. Попробуй другую, возможно эта ошибка характерна именно для Firebird, что-то, например, напартачили в дровах для SQLAlchemy. Хотя не припомню жалоб по этому поводу. Посмотри что будет, если использовать другую РСУБД, повторится ошибка или нет.

Попробуй использовать другую версию kinterbasdb (он виноват, я гарантирую это :-), смена версии SQLAlchemy врядли на что-то повлияет. Посмотри ВНЕЗАПНО какие ещё есть реализации dbapi для Firebird и подсунь их вместо kinterbasdb.

..bw
aaleksander
Сама база существует уже давно. Я пишу только клиент и менять саму СУБД не желательно.
Попробовал kinterbasdb 3.3 - таже же петрушка.
А на счет других dbApi, совместимых с sqlalchemy - ничего не нашел.
Придется, наверное, переходить на голый kinterbasedb. А так не хочется :-(
aaleksander
воткнул в одно место отладочный print,чтобы посмотреть какие параметры уходят в запрос. Получилось так:
(33,)
('33',)
(33,)
(Decimal("33"),)
т.е. идентификатор месторождения был и строкой и числом и еще каким-то числом, причем уже в двойных кавычках.
первые три - это запросы скважин по месторождению, они отрабатываются нормально. Последнее - запрос источников, по которому выходит ошибка.
Муть какая-то :-(
неужели никто не знает в чем причина?
PooH
Таблицы в базе соответствуют схеме? Конкретно поле rn в oil_field - действительно типа Integer?
aaleksander
Таблицы в базе соответствуют схеме? Конкретно поле rn в oil_field - действительно типа Integer?
Захожу отчитаться об успехах, а тут уже подсказка.
Буквально 20 минут назад догадался посмотреть. Так и есть: в oil_field - numeric(15, 0), а в src - integer.
Руки бы поотрывать тому программист :->
Чуть было не разачаровался в алхимии.
Всем спасибо за участие. Вопрос решен.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB