gpt4 book ai didi

python - 如何为所有 Flask-SQLAlchemy 模型继承自定义构造函数

转载 作者:行者123 更新时间:2023-12-04 07:41:16 29 4
gpt4 key购买 nike

我的代码:

# db.py
class NewModel(Model):
user = sa.Column(sa.String(256), nullable = False, default = 'User')
uploaded = sa.Column(sa.DateTime, nullable = False, default = datetime.utcnow)

def __init__(self, **kwargs):
kwargs['user'] = session['username']

super().__init__(**kwargs)

def save(self):
db.session.add(self)
db.session.commit()

db = SQLAlchemy(model_class = NewModel)
# upload_file.py
class UploadFile(db.Model):
id = db.Column(db.Integer, primary_key = True)
filename = db.Column(db.String(256), nullable = False)
path = db.Column(db.String(256), nullable = False, unique = True)

def __init__(self, file):
self.file = file

kwargs = {
'filename': file.filename,
'path': secure_filename(file.filename)
}

super().__init__(**kwargs)

def valid(self):
return self.file is not None and \
self.file.filename.strip() != ''
当我尝试创建 UploadFile 的实例时,它可以工作,但它不会调用 NewModel的构造函数。为什么?
我找到了 this issue ,但这并没有解决我的问题。
我尝试使用 orm.reconstructor 装饰器,但它也不起作用。

最佳答案

问题中的方法不起作用,因为 SQLAlchemy 修补了自己的 __init__方法到模型父类(super class)。 default implementation根据关键字参数分配实例属性值,这就是为什么即使定义的 __init__ 代码“有效”的原因方法没有被调用。
这可以通过 declarative_base 进行配置函数,但不幸的是 Flask-SQLAlchemy 没有直接公开它。
通过创建 abstract 可以获得想要的结果模型类,并从它继承应用程序的模型。

db = SQLAlchemy(app)


class NewModel(db.Model):

__abstract__ = True

user = sa.Column(sa.String(256), nullable=False, default="User")
uploaded = sa.Column(sa.DateTime, nullable=False, default=datetime.utcnow)

def __init__(self, **kwargs):
kwargs["user"] = session["username"]
super().__init__(**kwargs)

def save(self):
db.session.add(self)
db.session.commit()


# upload_file.py
class UploadFile(db.Model):
id = db.Column(db.Integer, primary_key=True)
filename = db.Column(db.String(256), nullable=False)
path = db.Column(db.String(256), nullable=False, unique=True)

def __init__(self, file):
kwargs = {
'filename': file.filename,
'path': secure_filename(file.filename)
}

super().__init__(**kwargs)
获得工作 __init__在模型父类(super class)( NewModel )上实现,我们需要制作一个自定义的构造函数并使用它,Flask 的 DefaultMeta元类和 NewModel class 创建一个新的声明性基类,该基类可以传递给 SQLAlchemy构造函数。
import sqlalchemy as sa
from sqlalchemy import orm
from flask import Flask
from flask_sqlalchemy import SQLAlchemy, Model, DefaultMeta

class NewModel(Model):

user = sa.Column(sa.String(256), nullable=False, default="User")
uploaded = sa.Column(sa.DateTime, nullable=False, default=datetime.utcnow)

def save(self):
db.session.add(self)
db.session.commit()

def my_declarative_constructor(self, **kwargs):
"""This will be the `__init__` method for all models."""
# Set attrs from kwargs using SQLALchemy's default constructor function.
orm.decl_api._declarative_constructor(self, **kwargs)
# Do custom attribute assignments.
self.user = session['username']

# Create a new declarative base class that combines our constructor function,
# Flask's default metaclass and our NewModel class.
Base = orm.declarative_base(
constructor=my_declarative_constructor, metaclass=DefaultMeta, cls=NewModel
)

# Use our declarative base class to create the db integration.
db = SQLAlchemy(app, model_class=Base)


# upload_file.py
class UploadFile(db.Model):
...

关于python - 如何为所有 Flask-SQLAlchemy 模型继承自定义构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67450491/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com