microsoft / mssql-django

The Microsoft Django backend for SQL Server provides a connectivity layer for Django on SQL Server or Azure SQL DB.
Other
347 stars 112 forks source link

How do I use sqlserver timestamp field? #42

Closed starryrbs closed 3 years ago

starryrbs commented 3 years ago

I did not find a mapping for the TIMESTAMP field.

class DatabaseWrapper(BaseDatabaseWrapper):
    vendor = 'microsoft'
    display_name = 'SQL Server'
    # This dictionary maps Field objects to their associated MS SQL column
    # types, as strings. Column-type strings can contain format strings; they'll
    # be interpolated against the values of Field.__dict__ before being output.
    # If a column type is set to None, it won't be included in the output.
    data_types = {
        'AutoField': 'int',
        'BigAutoField': 'bigint',
        'BigIntegerField': 'bigint',
        'BinaryField': 'varbinary(max)',
        'BooleanField': 'bit',
        'CharField': 'nvarchar(%(max_length)s)',
        'DateField': 'date',
        'DateTimeField': 'datetime2',
        'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
        'DurationField': 'bigint',
        'FileField': 'nvarchar(%(max_length)s)',
        'FilePathField': 'nvarchar(%(max_length)s)',
        'FloatField': 'double precision',
        'IntegerField': 'int',
        'IPAddressField': 'nvarchar(15)',
        'GenericIPAddressField': 'nvarchar(39)',
        'NullBooleanField': 'bit',
        'OneToOneField': 'int',
        'PositiveIntegerField': 'int',
        'PositiveSmallIntegerField': 'smallint',
        'SlugField': 'nvarchar(%(max_length)s)',
        'SmallAutoField': 'smallint',
        'SmallIntegerField': 'smallint',
        'TextField': 'nvarchar(max)',
        'TimeField': 'time',
        'UUIDField': 'char(32)',
    }
absci commented 3 years ago

I don't think Django have a field for TIMESTAMP, you could use DateTimeField with auto_now_add.

class myModel(models.Model):
    timestamp = models.DateTimeField(auto_now_add=True)
starryrbs commented 3 years ago

Thank you very much for your reply^_^. If I use DateTimeField with auto_now_add, the database throws an exception of "Cannot insert an explicit value into a timestamp column" because Django's auto_now_add is a value generated internally by Django. I want to ask if there are any good solutions or is there a problem with my use?

linkwithkk commented 3 years ago

It seems TIMESTAMP is deprecated and used to be an autogenerated value. This is now known as rowversion. Check here

Try and see if this works:

class myModel(models.Model):
    timestamp = models.DateTimeField()

If you want to initialize with default server time, change data type of column to datetime2 and then you can try the above code from @absci or this:

from datetime import datetime
class myModel(models.Model):
    timestamp = models.DateTimeField(default=datetime.now)
starryrbs commented 3 years ago

Thank you very much for your reply. @linkwithkk. Using the default cannot solve my problem, because the rowversion field cannot be changed and inserted. The default is still a value generated by python, and I expect the value generated by the database. I feel that this is a design problem of Django. I rewrote the save method of the model to solve this problem, but it is not a good solution.