I’m fiddling around to use Tryton as backend for Amavisd-new. So I let Tryton create the different tables and want to use Tryton to do some whitelist / blacklist configuration.
However, Amavisd-new wants to store data in several fields as bytea
which in Tryton are Binary
fields. Basically the content of the bytea
/ Binary
field have to be shown in Tryton which means converting / casting the data back to char
. Is this possible? How do I do that? I hoped to use sql_format
, sql_cast
or sql_type
but none of them worked.
I digged a bit deeper and found in the binary.py
and at http://docs.tryton.org/projects/server/en/latest/ref/models/fields.html#binary that I maybe have to do something with the context to get the format_
right.
I created a field
email = fields.Binary('Email address') email_str = fields.Function(fields.Binary('Email address'), 'get_mail')
Now I want the data stored in that column so I can display it with a Function
field.
The question is now Where do I have to change the context? Default ‘size’ is added to the context so you get the amount of characters of the string. Otherwise you will get the bytes returned, which I want. Putting context={...}
on the field itself doesn’t do anything. So I changed binary.py
a bit and then it worked. But I think it should be possible to do it through the context
You do not have to use the context. In the getter get_email
just convert the bytes into string using bytes.decode
.
Otherwise there may be an other option (not sure it works). You could set the widget to char
in the view for the Binay field.
It’s about CRUD of email addresses. Normally you would store them as plain text in de database as
email = fields.Char('Email address')
But Amavisd-new wants that field as a type bytea
which in Tryton is a binary
field:
email = fields.Binary('Email address')
So I just want to type in an email address and then store it as a binary string.
That didn’t work as I get an error Must be string, not bytes
But I got it working with an extra Function
field with a getter and setter
email = fields.Binary('Email address') email_str = fields.Function(fields.Char('Email address', 'get_mail_str', setter='set_mail_str') def get_mail_str(self, name=None): if self.email: with Transaction().set_context({ '<modelname>.email' : 'name', # doesn't matter what you put here -^ }): record = self.__class__(self.id) return(record.email.decode('utf-8')) return '' @classmethod def _set_mail_str(cls, emails, name, value): # Setting value is done by on_changes, # stolen from party.contact_mechanism pass @fields.depends('email_str') def on_change_email_str(self): self.email = self.email_str.encode()
Other suggestions are welcome!