Настроить spyne для пропуска поля, которого нет в запросе SOAP?

У меня есть модель SQLALchemy с таким столбцом:

updated_at = Column(DateTime, nullable=False, server_default=func.now(),
                        onupdate=func.now())

Что генерирует WSDL:

<xs:element name="updated_at" type="xs:dateTime" minOccurs="0"/>

В запросе на обновление поле updated_at отсутствует, и spyne сопоставляет его значение с None, что приводит к следующему:

IntegrityError: (IntegrityError) null value in column "updated_at" violates not-null constraint
 'UPDATE subcsription SET updated_at=%(updated_at)s WHERE subcsription.id = %(subcsription_id)s' {'subcsription_id': 27, 'updated_at': None}

Как я могу настроить spyne, чтобы вообще пропустить поле, если оно не передается в запросе SOAP?


person warvariuc    schedule 16.07.2013    source источник


Ответы (1)


Ваш интерфейс и схема вашей базы данных не обязательно должны совпадать 1-к-1. Вы можете определить отдельный объект, который не имеет элемента updated_at, и использовать его в качестве типа ввода в определении службы. Например.

class SomeObject(TableModel):
    __tablename__ = 'some_table'

    id = UnsignedInteger64(pk=True)
    updated_at = DateTime(server_default=func.now(), onupdate=func.now())
    some_data = Unicode

class SomeWriteObject(TableModel):
    __tablename__ = 'some_table'

    id = UnsignedInteger64(pk=True)
    some_data = Unicode

# or, you could do this:
class SomeWriteObject(TableModel):
    __tablename__ = 'some_table'
    _type_info = [ (k,v) for k,v in SomeObject._type_info.items()
                                                  if not k in ('updated_at',) ]
class SomeService(ServiceBase):
    @rpc(SomeWriteObject, _returns=UnsignedInteger64)
    def add_some_object(ctx, obj):
        ctx.udc.session.add(obj)
        ctx.udc.session.commit()
        return obj.id

Таким образом, updated_at будет исключено из запроса на вставку, что позволит базе данных заполнить это поле в соответствии с вашими инструкциями.

person Burak Arslan    schedule 18.07.2013
comment
Это означает ручное указание полей и исключение некоторых из них? Потому что прямо сейчас поля автоматически извлекаются из модели SQLALchemy. Я закончил тем, что исправил обезьяну-патч spyne, чтобы он не устанавливал значения полей входящего объекта, если они не были переданы в запросе SOAP. Это также решает проблему, когда поле spyne является необязательным, но не передается в SOAP-запросе, из-за чего оно перезаписывается None. - person warvariuc; 19.07.2013
comment
Это не нужно делать вручную, см. мое редактирование. Кроме того, не могли бы вы поделиться своим кодом исправления обезьяны в каком-нибудь github? Это может помочь другим. - person Burak Arslan; 20.07.2013