Изменения в методе класса __init__, похоже, не вступают в силу - PullRequest
0 голосов
/ 05 апреля 2019

У меня есть два конкретных класса моделей, которые дают мне ошибки во время моего тестирования, после проверки методов для каждого я был почти уверен, что мои проблемы были результатом опечаток с моей стороны.

Я сделализменения в обоих классах по мере необходимости, но повторный запуск тестов приводит к той же ошибке.Я даже пытался удалить мою схему и заново создать ее с помощью метода Flask-SQLAlchemy create_all(), но все еще сталкиваюсь с проблемами.

В классе Metrics переменные в методе __init__ были неправильнымии отсутствовали подчеркивания (то есть: self.name вместо self._name).Я решил эту проблему, изменив их на self._name и self._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 как None или NULL, хотя я создаю его с помощьюзначения для обоих параметров.

  2. Для HostMetricMapping Python вызывает исключение, поскольку он по-прежнему обрабатывает этот класс как имеющий только параметр metric_id, вместо того, чтобы также иметь host_id параметр I 've добавлено.

1 Ответ

0 голосов
/ 06 апреля 2019

Лучший способ переопределить __init__ при использовании flask-sqlalchemy - это использовать реконструктор .Инициализация объекта с помощью 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
...