Issue: Add option tu AutoField
Author: ghost
State: closed
Created: 2019-09-30 19:48:53

Hello...

I need add some extra options in field ID, currently automatic generate in:

```python
class Person(BaseModel):
    name = CharField()
    last_name = CharField()

```
Field ID generate like: `INTEGER NOT NULL PRIMARY KEY`, it's ok, but, I need:

`INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY`

Who to insert: `GENERATED BY DEFAULT AS IDENTITY`

I try with a custom field, but, I not know where. 

Thanks in advance.


If you're using postgresql, `AutoField` will be created as a `SERIAL` column. This automatically creates a sequence for the ID generation and sets up the default nextval. MySQL uses `AUTO_INCREMENT` and Sqlite just uses `INTEGER` (due to the aliasing of the rowid) for auto-incrementing integer fields.

It should be possible, if you really need this, to subclass and extend the `AutoField`. An existing example of this is the sqlite `AutoIncrementField` which inserts a special keyword (with special meaning in sqlite).

As long as the ordering of the constraints is not important, this should probably work:

```python
class IdentityField(AutoField):
    def ddl(self, ctx):
        node_list = super(IdentityField, self).ddl(ctx)
        return NodeList((node_list, SQL('generated by default as identity')))
```

I've gone ahead and added an implementation to `playhouse.postgres_ext`. Here is the code for the new field:

```python

class IdentityField(AutoField):
    field_type = 'INT'

    def __init__(self, generate_always=False, **kwargs):
        self._generate_always = generate_always
        super(IdentityField, self).__init__(**kwargs)

    def ddl(self, ctx):
        node_list = super(IdentityField, self).ddl(ctx)
        sql = SQL('GENERATED %s AS IDENTITY' %
                  ('ALWAYS' if self._generate_always else 'BY DEFAULT'))
        return NodeList((node_list, sql))
```

Wow, this is quickly... thanks...

Yes, order is important... with this code it create field correctly

```python
from peewee import *
from peewee import Entity, NodeList

class FirebirdAutoField(AutoField):
    extra = 'generated by default as identity'

    def ddl(self, ctx):
        accum = [Entity(self.column_name)]
        data_type = self.ddl_datatype(ctx)
        if data_type:
            accum.append(data_type)
        if self.unindexed:
            accum.append(SQL('UNINDEXED'))
        if self.extra:
            accum.append(SQL(self.extra))
        if self.primary_key:
            accum.append(SQL('PRIMARY KEY'))
        if not self.null:
            accum.append(SQL('NOT NULL'))
        if self.sequence:
            accum.append(SQL("DEFAULT NEXTVAL('%s')" % self.sequence))
        if self.constraints:
            accum.extend(self.constraints)
        if self.collation:
            accum.append(SQL('COLLATE %s' % self.collation))
        return NodeList(accum)
```

Get
```
30/09/2019 15:43:19 - DEBUG - CREATE TABLE "person" ("id" INTEGER generated by default as identity PRIMARY KEY NOT NULL, "name" VARCHAR(255) NOT NULL, "last_name" VARCHAR(255) NOT NULL)
```

Very thank, best regards


> Yes, order is important... with this code it create field correctly

Idk, I tested against postgresql with the code I linked and it appears to work correctly. Looking at the postgres syntax diagram it seems to agree that the order of the column constraints isn't important. At any rate, if that works for you, alright.

Didn't see that you were trying to use firebird. Makes sense now.

Yes, I used Firebird (I preferred Postgres :+1: ) , but not Firebird server, Firebird embedded in Base de LibreOffice. With peewee, now the work it's very funny, many thanks.

Well, shoot -- I knew this seemed familiar but I was looking in the wrong modules. I've already implemented `IdentityField` in `peewee.py`. I merged the implementations:

http://docs.peewee-orm.com/en/latest/peewee/api.html#IdentityField

It's great, now it's more easy... test with Firebird/Base, work fine, thanks

```
01/10/2019 11:42:04 - DEBUG - CREATE TABLE "person" ("id" INT GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY, "name" VARCHAR(255) NOT NULL, "last_name" VARCHAR(255) NOT NULL, "birthday" DATE)
```