First of all, at the risk of asking a silly question - is there actually a
reason to store this secondary ID in the database rather than just have it
calculated on the fly as-needed using a virtual field? Assuming that you've
got a created_date field already in the table that'll give you the month
portion and then there's definitely an id field to give you that so just
let web2py figure it out for you on-the-fly
Field.Virtual('human_id', lambda row: int(row.your_table.created_date.
strftime('%y%m00000')) + row.your_table.id)
The above would cause a record created today (2017-03-05) that had id = 123
to return a human_id of 170300123 which is I think what you want. Note the
extra zeros tacked on to the end of the strftime they are important so that
when you add the ID you don't accidentally increment your month number - be
sure to include enough to ensure that you can cover the highest realistic
record ID (and then add an extra zero :D). Alternatively, you may wish to
consider changing your human ID format to something like yymm-###### so
that you don't have to worry about inadvertently messing up your date
related portion and it is perhaps slightly easier for humans to understand
which is presumably important because I don't get why you'd want to include
the year and month if it isn't supposed to mean anything to the user.
db.your_table.human_id = Field.Virtual('human_id', lambda row:
'{0}-{1}'.format(row.your_table.created_date.strftime('%y%m') +'-' + row.
your_table.id), table_name = 'your_table')
If you need to actually store it in the database then you'll have to work
more. Sadly, web2py's computed fields won't work because they don't know
the ID before the insert. That leaves you with doing it DB side. MySQL
appears to only lets you have one auto-increment per table so unfortunately
you can't have both your actual primary key ID and a second human readable
monthly ID (that would intentionally be reset to something like 1703000000
this month and 1704000000 next). What I'd consider is creating a DB
trigger that would take care of automatically populating your secondary ID
for you all within the database so that there's nothing for you to manage.
So on insert the database could automatically look at the date (or use an
existing created_date field) and the current auto-increment number and
combine as needed and store it for you.
~Brian
On Sunday, March 5, 2017 at 11:26:51 AM UTC-6, Paul Ellis wrote:
>
> I want to have a numbering system which is 2 digit year, 2 digit month and
> then an autoincrement number which resets each month. 1703#####
>
> Currently using SQLite with a view to move to MYSQL in future. The MYSQL
> examples I have found suggest using a composite primary key, which doesn't
> seem to fit too well with web2py.
>
> The reason I am trying for autoincrement is so the database ensures the
> numbers are unique. I am willing to look at another way if I am sure I
> won't end up with 2 identical numbers.
>
> At the moment I have it working with
> datetime.date.today().strftime('%y%m') + id. So I am half way there, but
> can't see how to reset each month. I guess I can check for the highest
> number in the database programmatically, but I am worried about duplicate
> numbers with a high number of users. This also seems like if the document
> with the highest number was deleted (but possibly already printed), then
> the number will be reused.
>
> The program uses the actual primary key for all backend work. This is just
> an identifier for humans, but the documents produced by the program can't
> afford to have the same number as another document.
>
> Can someone give me a nudge in the right direction, I am a bit stuck?
>
--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.