'How to create generated column in Flask-SQLAlchemy?

This SQL is OK

CREATE TABLE `calendar` (
  `dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `d` date as (dt),
  `t` time as (dt)
);

How to create this table in Flask-SQLAlchemy?

class Calendar(db.Model):
    __table_args__ = {'mysql_collate': 'utf8_general_ci', 'mysql_engine':'InnoDB'}

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    dt = db.Column(db.DateTime, nullable=False, server_default=db.func.current_timestamp())
    d = ???
    t = ???

db.create_all()

This is error

class Calendar(db.Model):
    __table_args__ = {'mysql_collate': 'utf8_general_ci', 'mysql_engine':'InnoDB'}

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    dt = db.Column(db.DateTime, nullable=False, server_default=db.func.current_timestamp())
    d = db.ColumnProperty(db.Date,dt)
    t = db.ColumnProperty(db.Time,dt)


Solution 1:[1]

Perhaps this is not exactly what you want, but still: I'd suggest to use a hybrid_property instead (see documentation here), like so:

from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Float, Dat
from datetime import datetime

Base = declarative_base()

class User(Base):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True)
    firstname = Column(String(50))
    lastname = Column(String(50))
    birthdate = Column(DateTime, nullable=False, )

    @hybrid_property
    def birthyear(self):
        return self.birthdate.strftime("%Y/%m/%d")

    @hybrid_property
    def birthtime(self):
        return self.birthdate.strftime("%H:%M:%S")
    
us = User(firstname="Jon", 
    lastname="Snow",
    birthdate=datetime(1986, 12, 26, 23, 59, 59))

print(us.firstname, us.lastname, us.birthyear, us.birthtime)

Solution 2:[2]

This works for me

geom is the referenced column
expire_on_flush avoids instertions or uptates in computed columns.

distance = column_property(db.Column(db.Float,Computed("Round((st_length(geom,false)::numeric /1000),2)",True),nullable=True),expire_on_flush= True)

Hope it works

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 CoolCoder