В настоящее время у меня есть модель SQLAlchemy User
, с которой связаны два типа измерений: вес и рост. Они добавляются как внешние ключи.
class User(UserMixin, db.Model):
__tablename__ = "user"
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(100), unique=True)
password = db.Column(db.String(100))
name = db.Column(db.String(1000))
weight = db.relationship("Weight", cascade="all,delete")
height = db.relationship("Height", cascade="all,delete")
class Weight(db.Model):
__tablename__ = "weight"
id = db.Column(db.Integer, primary_key=True)
date = db.Column(db.DateTime)
weight = db.Column(db.Float)
user_id = db.Column(db.Integer, db.ForeignKey("user.id", ondelete="CASCADE"))
class Height(db.Model):
__tablename__ = "height"
id = db.Column(db.Integer, primary_key=True)
date = db.Column(db.DateTime)
height = db.Column(db.Float)
user_id = db.Column(db.Integer, db.ForeignKey("user.id", ondelete="CASCADE"))
Я хочу иметь возможность добавлять больше типов измерений без необходимости каждый раз перестраивать структуру базы данных. Поэтому я подумал об использовании общей модели c Measurement
, в которой есть столбец для типа измерения (а не Enum
, чтобы я мог легко добавлять новые типы):
class User(UserMixin, db.Model):
__tablename__ = "user"
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(100), unique=True)
password = db.Column(db.String(100))
name = db.Column(db.String(1000))
measurements = db.relationship("Measurement", cascade="all,delete")
@property
def weight(self):
pass # <-- No idea what to do here
@property
def height(self):
pass # <-- No idea what to do here
class Measurement(db.Model):
__tablename__ = "measurement"
id = db.Column(db.Integer, primary_key=True)
date = db.Column(db.DateTime)
value = db.Column(db.Float)
user_id = db.Column(db.Integer, db.ForeignKey("user.id", ondelete="CASCADE"))
measurement_type_id = db.Column(db.Integer, db.ForeignKey('measurement_type.id'))
measurement_type = db.relationship("MeasurementType")
class MeasurementType(db.Model):
__tablename__ = "measurement_type"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100))
unit = db.Column(db.String(100), nullable=True)
С этим новым модель, как мне получить только вес, например? В текущих моделях это так просто, где current_user
- это текущий пользователь, вошедший в систему:
current_user.weight
Но я предполагаю, что это должно быть примерно так:
current_user.measurements.filter(Measurement.measurement_type == "Weight")
(Что не работает, поскольку current_user.measurements
возвращает список.)
Аналогично, как мне затем добавить новое значение к измерениям? В настоящее время я делаю это:
current_user.weight.append(Weight(date=date, weight=weight))
db.session.commit()
Нужно ли мне в основном копировать низкоуровневую реализацию relationship
, чтобы фильтровать по двум параметрам: идентификатору пользователя и типу измерения?
Или я могу как-то добиться этого с помощью прокси-сервера ? Или (правильно) используя аргумент primaryjoin
из relationship
?