Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Column default value persisted to the table

I am currently using a Column that has the following signature:

Column('my_column', DateTime, default=datetime.datetime.utcnow)

I am trying to figure out how to change that in order to be able to do vanilla sql inserts (INSERT INTO ...) rather than through sqlalchemy. Basically I want to know how to persist the default on the table without lossing this functionality of setting the column to the current utc time.

The database I am using is PostgreSQL.

like image 761
hyperboreean Avatar asked Mar 18 '11 12:03

hyperboreean


People also ask

What default value gets stored in columns of table?

NULL is the default value as it stands for “Absence of value”.

What is the default value by DEFAULT of a column?

Default values can be NULL, or they can be a value that matches the data type of the column (number, text, date, for example).

What is persisted column?

Computed columns can be persisted. It means that SQL Server physically stores the data of the computed columns on disk. When you change data in the table, SQL Server computes the result based on the expression of the computed columns and stores the results in these persisted columns physically.


2 Answers

There are multiple ways to have SQLAlchemy define how a value should be set on insert/update. You can view them in the documentation.

The way you're doing it right now (defining a default argument for the column) will only affect when SQLAlchemy is generating insert statements. In this case, it will call the callable function (in your case, the datetime.datetime.utcnow function) and use that value.

However, if you're going to be running straight SQL code, this function will never be run, since you'll be bypassing SQLAlchemy altogether.

What you probably want to do is use the Server Side Default ability of SQLAlchemy.

Try out this code instead:

from sqlalchemy.sql import func
...
Column('my_column', DateTime, server_default=func.current_timestamp())

SQLAlchemy should now generate a table that will cause the database to automatically insert the current date into the my_column column. The reason this works is that now the default is being used at the database side, so you shouldn't need SQLAlchemy anymore for the default.

Note: I think this will actually insert local time (as opposed to UTC). Hopefully, though, you can figure out the rest from here.

like image 143
Mark Hildreth Avatar answered Oct 05 '22 13:10

Mark Hildreth


If you wanted to insert UTC time you would have to do something like this:

from sqlalchemy import text
...
created = Column(DateTime,
                 server_default=text("(now() at time zone 'utc')"),
                 nullable=False)
like image 37
Dan P. Avatar answered Oct 05 '22 12:10

Dan P.