我正在使用SQLAlchemy和SQLite创建我的第一个数据库项目。我想将两个实体连接为关系数据库的关系模型。来源如下:
class Models(Base):
__tablename__ = "models"
id_model = Column(Integer, primary_key=True)
name_of_model = Column(String, nullable = False)
price = Column(Integer, nullable = False)
def __init__(self, name_of_model):
self.name_of_model = name_of_model
class Cars(Base):
__tablename__ = "cars"
id_car = Column(Integer, primary_key=True)
id_equipment = Column(Integer, nullable = False)
id_package = Column(Integer, nullable = False)
id_model = Column(Integer, ForeignKey('Models'))
model = relationship("Models", backref=backref('cars', order_by = id_model))
Run Code Online (Sandbox Code Playgroud)
我想建立这样的关系:https : //imgur.com/af62zli
发生的错误是:
The foreign key associated with column 'cars.id_model' could not find table 'Models' with which to generate a foreign key to target column 'None'.
Run Code Online (Sandbox Code Playgroud)
任何想法如何解决这个问题?
从文档:
参数to
ForeignKey最常见的是形式的字符串<tablename>.<columnname>,或者是远程模式中的表或形式的“所有者”<schemaname>.<tablename>.<columnname>。它也可能是一个实际的Column对象...
在定义您的ForeignKeyon时,Cars.id_model您传递了类名('Models')的字符串形式,这不是可接受的形式。
但是,您可以使用以下选项之一成功定义外键:
ForeignKey(Models.id_model)
Run Code Online (Sandbox Code Playgroud)
这使用实际Column对象来指定外键。这种方法的缺点是,您需要在名称空间中添加该列,这会增加将模型导入模块中的复杂性(如果未在该模块中定义),并且还可能使您担心模型的实例化顺序。这就是为什么使用基于字符串的选项之一更为普遍的原因,例如:
ForeignKey('models.id_model')
Run Code Online (Sandbox Code Playgroud)
请注意,此示例不包括类名的字符串版本(不是M odels.id_model),而是包括表名的字符串版本。字符串版本意味着所需的表对象仅在需要时才解析,因此避免了处理的复杂性Column对象本身。
在这种情况下有效的另一个有趣示例:
ForeignKey('models')
Run Code Online (Sandbox Code Playgroud)
如果两个表上两个列的名称相同,则SQLAlchemy似乎从表中推断出该列。如果您更改id_model示例中任一列定义的名称,以使它们的名称不同,则该列定义将停止工作。另外,我还没有找到足够好的文档,而且它不够明确,因此不确定是否真的值得使用,是否只是出于完整性而提及,因为我发现它很有趣。ForeignKey._column_tokens()关于columnarg的可接受格式,源代码中的注释似乎比文档更明确:
# A FK between column 'bar' and table 'foo' can be
# specified as 'foo', 'foo.bar', 'dbo.foo.bar',
# 'otherdb.dbo.foo.bar'. Once we have the column name and
# the table name, treat everything else as the schema
# name.
Run Code Online (Sandbox Code Playgroud)