1

So I'm using sqlmodel (sqlalchemy with pedantic) and I have something like this model:

class SequencedBaseModel(BaseModel):
    sequence_id: str = Field(alias="sequence_id")

    @declared_attr
    def sequence_id(cls):
        return Column(
            'sequence_id',
            VARCHAR(50),
            server_default=text(f"SELECT '{cls.__tablename__}_'"
                                f" + convert(varchar(10), NEXT VALUE FOR dbo.sequence)"))


class Project(SequencedBaseModel, table=True):
    pass

with SqlAlchemy I now try to insert rows over an API. The request-json looks like this:

{
    "name": "test_project"
}

So the sequence_id is not entered, and will be generated by database. SqlAlchemy generates a statement like:

insert into Project (name, sequence_id) values ("test_project", null)

which wouldn't be wrong, if it wasn't SQL Server... therefore I get the exception that NULL cannot be inserted into the column sequence_id. For SQL Server we need the default keyword instead of null. If I execute the statement

insert into Project (name, sequence_id) values ("test_project", default)

it works...

any idea on how to make sql-alchemy to use default instead of null/None if there is a default-value?

I also tried to change the sequence_id to use something like

sequence_id: str = Field(alias="sequence_id", default=sqlalchemy.sql.elements.TextClause('default'))

but this doesn't work either

Dale K
  • 25,246
  • 15
  • 42
  • 71
Matthias Burger
  • 5,549
  • 7
  • 49
  • 94

1 Answers1

1

Use the server_onupdate argument to apply the text function with the 'default' keyword, that is already defined when update is performed.

See example below which is applied to your code:

    @declared_attr
    def sequence_id(cls):
        return Column(
            'sequence_id',
            VARCHAR(50),
            server_default=text(f"SELECT '{cls.__tablename__}_'"
                                f" + convert(varchar(10), NEXT VALUE FOR dbo.sequence)"),
            server_onupdate=text('default')
        )

The server_onupdate argument is part of SQLAlchemy's Column constructor.
It is used to specify the value that should be used when the column is updated.
It allows the definition of a SQL expression or keyword to be used instead of explicitly providing a value during updates.

djmonki
  • 3,020
  • 7
  • 18