Reputation: 43
I have two particular model classes that are giving me errors during my testing, upon inspecting the methods for each I was pretty certain my issues were the result of typos on my part.
I've made the changes in both classes as needed, but re-running the tests produces the same error. I even tried dropping my schema and re-creating it with Flask-SQLAlchemy's create_all()
method, but I still run into issues.
In the Metrics
class, the variables in the __init__
method were wrong and were missing underscores (Ie: self.name
instead of self._name
). I addressed that by changing them to self._name
and self._metric_type
In the HostMetricMapping class, I needed to add the host_id
parameter to the __init__
method, since I had forgotten it the first time. So, I added it.
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)
The issues I encounter are:
When trying to instantiate an instance of Metrics
and add it into the database, SQLAlchemy raises an IntegrityError
because I have the _name
column set to not null
, and SQLAlchemy inherits the values for both _name
and _metric_type
as None
or NULL
, even though I instantiate it with values for both parameters.
For HostMetricMapping, Python raises an exception because it still treats that class as only having the metric_id
parameter, instead of also having the host_id
parameter I've added.
Upvotes: 0
Views: 2189
Reputation: 13009
A better way to override __init__
when using flask-sqlalchemy is to use reconstructor. Object initialization with sqlalchemy is a little tricky, and flask-sqlalchemy might be complicating it as well.. anyways, here's how we do it:
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
Upvotes: 3