Flask-SQLAlchemy在父表中添加了不必要的行(关系表)

时间:2016-08-07 19:01:30

标签: python mysql flask flask-sqlalchemy

我最近尝试使用Flask构建一个小型网络应用程序。对于数据库'东西'我使用Flask-SQLAlchemy,现在我试图获得两个对象之间的关系 我有一个'项目'表和文件'表和它应该是一对多的关系,所以x文件可以与一个项目相关联(实际上,当我发现当前的问题时,将来会有更多的关系。)
我已经创建了一个输入掩码模板,因此用户可以上传文件并通过下拉列表将其链接到项目,该下拉列表中填充了存储在其表中的现有项目。那是相应的观点:

@app.route('/admin/upload/', methods=('GET', 'POST'))
def upload():
form = forms.UploadForm()

if not os.path.isdir(app.config['UPLOAD_FOLDER']):
    os.mkdir(app.config['UPLOAD_FOLDER'])
    print('Folder created')  

form.projectId.choices = []

for g in models.Project.query.order_by('name'):
    form.projectId.choices.append((g.id, g.name))

if form.validate_on_submit():
    filename = secure_filename(form.fileUpload.data.filename)
    filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
    assocProject = models.Project(name=models.Project.query.filter_by(id=form.projectId.data).first().name)

    form.fileUpload.data.save(filepath)
    prepedFile = models.File(path=filepath, project=assocProject)

    print(prepedFile)
    print(form.projectId.data)

    db.session.add(prepedFile)
    db.session.commit()

    return 'success'
else:
    filename = None
return render_template('upload.html', form=form, filename=filename) 

准备好的文件应该是File-Class的一个实例,它将链接的Project-instance作为属性,因此提交应该有效。

    class Project(db.Model):
__tablename__ = 'project'

id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64))
file = db.relationship('File', backref="projects")
post = db.relationship('Post', backref="projects")

def __init__(self, name):
    self.name = name

def __repr__(self):
    return '<Project %r>' % self.name


class File(db.Model):
__tablename__ = 'file'

id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64))
path = db.Column(db.String(64))
type = db.Column(db.String(6))

projectId = db.Column(db.Integer, db.ForeignKey('project.id'))
project = db.relationship('Project', backref='files')

def __init__(self, path, project):
    self.path = path
    self.project = project

    fullName = re.search('[a-zA-Z0-9]*\.[a-zA-Z]{2,}', path)
    splitName = fullName.group(0).split('.')
    self.name = splitName[0]
    self.type = splitName[1]

def __repr__(self):
    return '<File %r %r %r %r>' % (self.name, self.type, self.path, self.project)

现在出现问题:当我尝试上传文件时,它可以工作,文件信息存储在文件表中,但它会在项目表中创建一个新条目,并将其id链接到文件条目。例如,如果项目条目如下:name = TestProj1,id = 1并且我尝试链接上传到项目,它将创建第二个项目:name = TestProj1,id = 2。
这是我的斗争,我无法弄清楚什么是错的。也许你们当中有些人。我感谢任何帮助!

P.S。也许它是相关的,这里是我写的形式:

class UploadForm(Form):
    fileUpload = FileField(label='Deine Datei')
    projectId = SelectField(u'Projekte', coerce=int)

1 个答案:

答案 0 :(得分:0)

每次都会创建一个新的Project

assocProject = models.Project(name=models.Project.query.filter_by(id=form.projectId.data).first().name)

这有两件事。首先,它找到具有指定id的第一个项目。其次,它将该项目的名称传递给Project(),使用相同的名称创建一个新实例。

你真正想要的是

assocProject = models.Project.query.get(form.projectId.data)