Python SQLAlchemy : Reflecting the database breaks default/onupdate methods?

标签 python postgresql flask sqlalchemy flask-sqlalchemy

我有两个独立的 SQLAlchemy 接口(interface)连接到 Postgres 数据库。在 Flask 应用程序的上下文中,第一个接口(interface)包含此模型:

app = create_app() # sets the SQLAlchemy Database URI, etc.
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    created_at = db.Column(db.DateTime, default=datetime.datetime.utcnow)
    updated_at = db.Column(db.DateTime, onupdate=datetime.datetime.utcnow)
    name = db.Column(db.String, nullable=False)

第二个接口(interface)不是通过 Flask —— 相反,它是一个监听特定事件的脚本,在这种情况下,它旨在执行一些计算并更新数据库中的行。为此,我让 SQLAlchemy 反射(reflect)了现有的数据库:

from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy.orm import mapper, sessionmaker
from sqlalchemy.ext.automap import automap_base
from os import environ

dbPath = "postgresql://" + ...
engine = create_engine(dbPath)

Base = automap_base()
Base.prepare(engine, reflect=True)

metadata = MetaData(engine)

class User(object):
    pass

users = Table('user', metadata, autoload=True, autoload_with=engine)
mapper(User, users)

Session = sessionmaker(bind=engine)
session = Session()

我现在遇到的问题是:当我使用第一个界面创建新条目或更新条目时,事情按预期工作,created_at updated_at 字段已适当更新。

但是,当我使用第二个界面时——导入代码并使用 session.query(User) 获取条目并更新它时,updated_at 字段没有改变。此外,当我使用此界面创建新用户时,虽然它按预期创建了新行,但它既不填充 created_at 也不填充 updated_at 字段。

我的问题:

  1. 为什么会这样?为什么反射似乎破坏了 default/onupdate 方法?
  2. 我该如何解决这个问题?

最佳答案

defaultonupdate 在 Python 中完全由客户端处理,因此无法从数据库反射(reflect)出来。参见 "Limitations of Reflection" .在 default 的情况下,您可以使用 server_default :

class User(db.Model):
    ...
    created_at = db.Column(db.DateTime,
                           server_default=text("now() at time zone 'UTC'"))

对于 onupdate,您必须编写一个数据库触发器并使用 server_onupdate=FetchedValue() .

另一方面,您可以避免所有这些,只需将模型与应用程序代码分离到一个模块中,供 Flask 应用程序和脚本使用。这当然会涉及更多,因为您必须使用 vanilla SQLAlchemy 声明式而不是 Flask-SQLAlchemy 的自定义 db.Model 基础。或者,您可以使用 custom commands使用 Flask 来实现您的脚本,这将允许使用 Flask-SQLAlchemy 扩展。

关于Python SQLAlchemy : Reflecting the database breaks default/onupdate methods?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43359116/

相关文章:

python - 使用 Flask 上传图片和标签

javascript - 如何让这个 websocket 示例与 Flask 一起工作?

python - 使用 Scipy Signal 计算之前计算中的正余额

Python 参数解析 : command-line argument that can be either named or positional

python - 如何通过终端在 Linux Ubuntu 中打开 Anaconda Navigator

postgresql - 来自别名的 SQL 累积和

PostgreSQL。可以并行运行更新查询吗?

sql - 返回特定关联值发生变化的账户的所有历史记录

python - Pygame显示模块初始化和退出

javascript - Flask WTForms 的自定义属性