Исходные:
приложение на flask
инфраструктура бд - flask-sqlAlchemy + sqlite
особенности - прикладное ненагруженное приложение со сложной системой моделей данных, которые параллельно связаны и влияют друг на друга, выстраивая динамическую иерархическую систему, существующую параллельно в нескольких иерархических состояниях. Были выбраны реляционные БД.
class Attribute(db.Model):
id = db.Column(db.Integer, primary_key=True)
attributename= db.Column(db.String(120), index=True, unique=False)
source= db.Column(db.String(120), index=True, unique=False)
description = db.Column(db.Text, index=True)
class Criteria(db.Model):
id = db.Column(db.Integer, primary_key=True)
criteria= db.Column(db.String(64), index=True, unique=True)
class Classification(db.Model):
id = db.Column(db.Integer, primary_key=True)
source= db.Column(db.String(120), index=True, unique=False)
description = db.Column(db.Text, index=True)
class Node(db.Model):
id = db.Column(db.Integer, primary_key=True)
parent_id = db.Column(db.Integer, db.ForeignKey('node.id'))
attribute_id = db.Column(db.Integer, db.ForeignKey('attribute.id'))
criteria_id = db.Column(db.Integer, db.ForeignKey('criteria.id'))
classification_id = db.Column(db.Integer, db.ForeignKey('classification.id'))
left = db.Column("lft", db.Integer, index=True, nullable=False)
right = db.Column("rgt", db.Integer, index=True, nullable=False)
childs = db.relationship('Node', backref=db.backref("parent", remote_side=id),lazy="dynamic")
attribute= db.relationship('Attribute', backref='node')
criteria= db.relationship('Criteria', backref='node')
classification = db.relationship('Classification', backref='node')
Модель, с которой будет происходить большинство операций - Node. она выполняет и роль связывающей таблицы, и несет в себе информацию об иерархии. На базовом этапе я хочу, чтобы работала она. А потом я добавлю нужные параметры, чтобы использовать ее для организации и отображения других моделей. В данной редакции схема прошла проверку при инициализации и миграции баз данных, при создании всех сущностей, кроме Node. А вот попытка использовать модель Node ведет к ошибке бд (sqlite3.InterfaceError). Так как не выходит с одним связанным параметром, то остальные я не прописывал.
Как я использую эту модель (flask-wtforms):
class NodeForm(FlaskForm):
criteria_id = SelectField(u'Criteria', coerce=int)
submit = SubmitField('Add new')
@app.route('/add-node', methods=['GET', 'POST'])
def addnode():
criteria = Criteria.query.get(id)
form = NodeForm(request.POST, obj=criteria)
form.criteria_id.choices = [(g.id, g.criteria) for g in Criteria.query]
form = NodeForm()
if form.validate_on_submit():
criteria= Node(criteria_id=form.criteria_id.data)
db.session.add(criteria)
db.session.commit()
flash('New Node created!')
return redirect(url_for('addnode'))
return render_template('addnode.html', form=form)
Что нужно в этой форме: на страничке добавления новой сущности Node вывести список уже готовых связанных сущностей Criteria, из которого выбрать одну, идентификатор которой запишется в соответствующее поле (criteria_id в модели Node).
Это элементарные вещи, я многократно сверялся с мануалами и документацией, но не смог решить проблему, как описать связи в модели так, чтобы их можно было использовать.