【问题标题】:Changes to model class's __init__ method don't seem to be taking effect对模型类的 __init__ 方法的更改似乎没有生效
【发布时间】:2019-04-05 20:05:16
【问题描述】:

我有两个特定的模型类在我的测试过程中给了我错误,在检查每个方法后,我非常确定我的问题是我的拼写错误造成的。

我已根据需要对这两个类进行了更改,但重新运行测试会产生相同的错误。我什至尝试删除我的架构并使用 Flask-SQLAlchemy 的 create_all() 方法重新创建它,但我仍然遇到问题。

Metrics 类中,__init__ 方法中的变量错误并且缺少下划线(即:self.name 而不是self._name)。我通过将它们更改为 self._nameself._metric_type 来解决这个问题

在 HostMetricMapping 类中,我需要将 host_id 参数添加到 __init__ 方法中,因为我第一次忘记了它。所以,我添加了它。

class Metrics(_database.Model):



    __tablename__ = 'Metrics'
    _ID = _database.Column(_database.Integer, primary_key=True)
    _name = _database.Column(_database.String(45), nullable=False)
    _metric_type = _database.Column(_database.String(45))
    _host_metric_mapping = _database.relationship('HostMetricMapping', backref='_parent_metric', lazy=True)


    def __init__(self, name, metric_type):
        self._name = name # This line used to say self.name, but was changed to self._name to match the column name
        self._metric_type = metric_type # This line used to say self.metric_type, but was changed to self._metric_type to match the column name


    def __repr__(self):
        return '{0}'.format(self._ID)



class HostMetricMapping(_database.Model):



    __tablename__ = 'HostMetricMapping'
    _ID = _database.Column(_database.Integer, primary_key=True)
    _host_id = _database.Column(_database.Integer, _database.ForeignKey('Hosts._ID'), nullable=False)
    _metric_id = _database.Column(_database.Integer, _database.ForeignKey('Metrics._ID'), nullable=False)
    _metric = _database.relationship('MetricData', backref='_metric_hmm', lazy=True)
    _threshold = _database.relationship('ThresholdMapping', backref='_threshold_hmm', lazy=True)


    def __init__(self, host_id, metric_id):
        self._host_id = host_id # This line and it's corresponding parameter were missing, and were added
        self._metric_id = metric_id


    def __repr__(self):
        return '{0}'.format(self._ID)

我遇到的问题是:

  1. 当尝试实例化 Metrics 的实例并将其添加到数据库中时,SQLAlchemy 会引发 IntegrityError,因为我将 _name 列设置为不是 null,并且 SQLAlchemy 继承了_name_metric_type 都作为 NoneNULL,即使我用两个参数的值来实例化它。

  2. 对于 HostMetricMapping,Python 会引发异常,因为它仍然将该类视为只有 metric_id 参数,而不是我添加的 host_id 参数。

【问题讨论】:

  • 这可能发生在父类实现__new__或使用元类的情况下,这通常是ORM的情况
  • 原谅我的无知,但在这种情况下我的解决方法是什么?在对文件本身进行更改后,我删除了我的架构并重新制作了它,所以我不知道以前的值将被缓存/存储在哪里,它们显然仍然被引用
  • 我会去_database.Model的定义并检查它是如何实例化的。但是,从这个 sn-p 我不能说它是从哪里导入的
  • SQLA 模型使用__init__,正如您所期望的那样。请提供minimal reproducible example 和错误的完整回溯。

标签: python sqlalchemy flask-sqlalchemy


【解决方案1】:

在使用 flask-sqlalchemy 时覆盖 __init__ 的更好方法是使用 reconstructor。使用 sqlalchemy 进行对象初始化有点棘手,flask-sqlalchemy 也可能使其复杂化。无论如何,我们是这样做的:

from sqlalchemy.orm import reconstructor

class MyModel(db.Model):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.init_on_load()

    @reconstructor
    def init_on_load(self):
        # put your init stuff here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-25
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多