0

I have a SQLALchemy model with such a column:

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

Which generates WSDL:

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

In the update request updated_at field is missing, and spyne maps its value to None causing this:

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}

How can i set up spyne to skip the field at all when it is not passed in SOAP request?

warvariuc
  • 57,116
  • 41
  • 173
  • 227

1 Answers1

1

Your interface and your database schema don't need to match 1-to-1. You can define a separate object that doesn't have the updated_at member and use it as the input type in your service definition. E.g.

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

This way updated_at will be left out in the insert query which will leave it to the database to fill that field according to your instructions.

Burak Arslan
  • 7,671
  • 2
  • 15
  • 24
  • This means manually specifying fields and excluding some of them? Because right now fields are automatically extracted from a SQLALchemy model. I ended up monkey-patching spyne to not set field values of an incoming object if they were not passed in a SOAP request. This also solves a problem, when a spyne field is optional, but it was not passed in SOAP request, causing it to be overwritten with `None`. – warvariuc Jul 19 '13 at 04:09
  • This doesn't need to be done manually, see my edit. Also, could you share your monkey-patching code in some github gist? It could help others. – Burak Arslan Jul 20 '13 at 11:12