背景
我有一个用户可以上传文件的项目。在数据库中,我想将文件路径存储到上传的文件中。
DB中有2个表; Users
& FileUploadPath
。这些表格具有一对一的关系。
我目前使用的Flask-SQLAlchemy模型是:
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////{}'.format(os.path.join(os.getcwd(), "test.db"))
db = SQLAlchemy(app)
class User(db.Model):
__tablename__ = 'Users'
userid = db.Column(db.Integer, primary_key=True, autoincrement=True)
fname = db.Column(db.String(80), nullable=False)
lname = db.Column(db.String(80), nullable=False)
phonenum = db.Column(db.String(10), nullable=False)
email = db.Column(db.String(60), nullable=False)
password = db.Column(db.String(60), nullable=False)
validated = db.Column(db.Boolean, default=False)
child = db.relationship('FileUploadPath', uselist=False, backref='Users')
class FileUploadPath(db.Model):
__tablename__ = 'FileUploadPath'
fileUploadID = db.Column(db.Integer, primary_key=True, autoincrement=True)
w9FilePath = db.Column(db.String(60), nullable=False)
gcFilePath = db.Column(db.String(60), nullable=False)
livescanFilePath = db.Column(db.String(60), nullable=False)
gcaFilePath = db.Column(db.String(60), nullable=False)
userID = db.Column(db.Integer, db.ForeignKey('Users.userid'))
要创建新用户,请使用以下命令:
newuser = User(fname='Bob', lname='Smith', phonenum='6551234567', email='bobsmith@gmail.com', password='fe287943hfbwiqey281')
使用此命令,我希望在userID
表中看到FileUploadPath
;目前仅在Users
表中看到已创建的用户,但在NULL
列中只看到userID
。
通过查询,我还希望查看与特定用户相关的所有上传文件路径信息。
模型设置之间的关系是否正确?如果没有,我将如何宣布这种关系?
修改
我想要做的是将fileUploadID
存储在Users
表内。应为每个创建的新用户插入FileUploadPath
表中的新行。因为当我创建一个新用户时,FileUploadPath
表中的所有列都将为空;因为新用户尚未上传任何文件。
答案 0 :(得分:1)
表关系看起来没问题,除了backref='Users'
是一个奇怪的名称选择,因为这将向FileUploadPath
添加“用户”属性,这不遵循命名约定其余的属性。我希望这可能是backref='user'
。
现在,主要问题是您没有指定FileUploadPath
应该与newuser
相关联,因此它没有在引用ID的FileUploadPath
中插入任何条目newuser
。或者您可能已插入了要与FileUploadPath
关联的新newuser
,但您未在示例中显示该代码。在任何情况下,它都不知道哪个FileUploadPath
与哪个User
相关联,并且它不会为每个FileUploadPath
自动创建新的User
,所以当您只需创建一个新的User
,或者如果您单独创建新的User
和FileUploadPath
但未链接它们,则最终不会与FileUploadPath
相关联您的新User
。
因此,您需要做的是通过添加FileUploadPath
参数将newuser
与child=newFileUploadPath
相关联(其中newFileUploadPath
是已构建的FileUploadPath
User
}}当您调用User
构造函数,或单独构建和添加FileUploadPath
和newuser.child = newFileUploadPath
个对象,并设置newFileUploadPath.user = newuser
或newFileUploadPath.user
时。 (请注意,backref='user'
会假设我的建议FileUploadPath
更改。)
修改:这是MVCE,其中显示了如何为用户添加文件上传。但是,最初创建用户时文件上载不存在,这应该是预期的行为。你绝对不应该在uselist=False
中包含所有空字符串的条目。此外,如果您计划每个用户最多允许上传4次,则需要通过删除Users.child
并将children
视为列表来使其成为多对一关系,并且也许还可以将其重命名为uploads
或import os
import sys
from sqlalchemy import Column, ForeignKey, Integer, String, Boolean
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy import create_engine
Base = declarative_base()
class User(Base):
__tablename__ = 'Users'
userid = Column(Integer, primary_key=True, autoincrement=True)
fname = Column(String(80), nullable=False)
lname = Column(String(80), nullable=False)
phonenum = Column(String(10), nullable=False)
email = Column(String(60), nullable=False)
password = Column(String(60), nullable=False)
validated = Column(Boolean, default=False)
child = relationship('FileUploadPath', uselist=False, backref='user')
class FileUploadPath(Base):
__tablename__ = 'FileUploadPath'
fileUploadID = Column(Integer, primary_key=True, autoincrement=True)
w9FilePath = Column(String(60), nullable=False)
gcFilePath = Column(String(60), nullable=False)
livescanFilePath = Column(String(60), nullable=False)
gcaFilePath = Column(String(60), nullable=False)
userID = Column(Integer, ForeignKey('Users.userid'))
engine = create_engine('sqlite:///')
Base.metadata.create_all(engine)
session_factory = sessionmaker(bind=engine)
session = session_factory()
# Insert a new user with no uploads:
newuser = User(fname='Bob', lname='Smith', phonenum='6551234567', email='bobsmith@gmail.com', password='fe287943hfbwiqey281')
session.add(newuser)
session.commit()
# Query for users and uploads:
print(session.query(FileUploadPath).count())
# 0
print(session.query(User).count())
# 1
print(session.query(User).one().child)
# None
# Insert an upload for the user:
newupload = FileUploadPath(w9FilePath='some_path', gcFilePath='another_path', livescanFilePath='yet_another_path', gcaFilePath='another_path_still', user=newuser)
session.add(newupload)
session.commit()
# Again, query for users and uploads:
print(session.query(FileUploadPath).count())
# 1
print(session.query(User).one().child)
# <FileUploadPath object>
print(session.query(User).one().child.w9FilePath)
# 'some_path'
。
(注意,此示例使用纯SQLAlchemy而不是Flask-SQLAlchemy,因此模型定义和数据库设置的某些部分可能与您的实现不同。)
CFRelease