【问题标题】:How to create generated column in Flask-SQLAlchemy?如何在 Flask-SQLAlchemy 中创建生成的列?
【发布时间】:2022-04-26 15:06:49
【问题描述】:

这个SQL没问题

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

如何在 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()

这是错误

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)

【问题讨论】:

  • 在我看来,当你已经有一个 DateTime 时,你正试图拥有单独的 DateTime 列;如果是这样的话,see here.
  • 是的,但我想使用生成的列来做到这一点

标签: python flask-sqlalchemy


【解决方案1】:

也许这不是完全您想要的,但仍然:我建议改用hybrid_property (see documentation here),如下所示:

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)

【讨论】:

  • 我使用生成的列,因为我只使用 SQLAlchemy 创建数据库。我实际上在我的 php 网站中使用了其他 ORM
  • 如果您只是使用 SQLAlchemy 创建数据库,并且已经知道如何在 SQL 中运行它,为什么不最后运行engine.execute("ALTER TABLE … ")?以See here 为例。
【解决方案2】:

这对我有用

geom 是引用列
expire_on_flush 避免在计算列中插入或更新。

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

希望有效果

【讨论】:

    猜你喜欢
    • 2014-10-15
    • 1970-01-01
    • 2018-06-15
    • 2016-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-07
    • 1970-01-01
    相关资源
    最近更新 更多