Question

I have a simple "Invoices" class with a "Number" attribute that has to be assigned by the application when the user saves an invoice. There are some constraints:

1) the application is a (thin) client-server one, so whatever assigns the number must look out for collisions
2) Invoices has a "version" attribute too, so I can't use a simple DBMS-level autoincrementing field

I'm trying to build this using a custom Type that would kick in every time an invoice gets saved. Whenever process_bind_param is called with a None value, it will call a singleton of some sort to determine the number and avoid collisions. Is this a decent solution? Anyway, I'm having a problem.. Here's my custom Type:

class AutoIncrement(types.TypeDecorator):
   impl = types.Unicode

   def copy(self):
       return AutoIncrement()

   def process_bind_param(self, value, dialect):
       if not value:
           # Must find next autoincrement value
           value = "1" # Test value :)
       return value

My problem right now is that when I save an Invoice and AutoIncrement sets "1" as value for its number, the Invoice instance doesn't get updated with the new number.. Is this expected? Am I missing something? Many thanks for your time!

(SQLA 0.5.3 on Python 2.6, using postgreSQL 8.3)

Edit: Michael Bayer told me that this behaviour is expected, since TypeDecorators don't deal with default values.

Was it helpful?

Solution

Is there any particular reason you don't just use a default= parameter in your column definition? (This can be an arbitrary Python callable).

def generate_invoice_number():
    # special logic to generate a unique invoice number

class Invoice(DeclarativeBase):
    __tablename__ = 'invoice'
    number = Column(Integer, unique=True, default=generate_invoice_number)
    ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top