我正在使用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))
我想建立这样的关系: 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'.
有什么办法解决这个问题吗?
答案 0 :(得分:4)
来自the docs:
ForeignKey
的参数通常是以下形式的字符串<tablename>.<columnname>
,或者用于远程模式或“所有者”中的表 格式为<schemaname>.<tablename>.<columnname>
。也可能是 实际的Column
对象...
在ForeignKey
上定义Cars.id_model
时,您传递了类名('Models'
)的字符串形式,这不是可接受的形式。
但是,您可以使用以下选项之一成功定义外键:
ForeignKey(Models.id_model)
这使用实际的Column
对象来指定外键。这种方法的缺点是,您需要在名称空间中添加该列,这增加了将模型导入模块时的复杂性(如果未在模块中定义),并且还可能使您担心模型的实例化顺序。这就是为什么使用基于字符串的选项之一(例如:
ForeignKey('models.id_model')
请注意,此示例未包含类名的字符串版本(不是 M odels.id_model),而是表名的字符串版本。字符串版本意味着仅在需要时才解析所需的表对象,因此避免了处理Column
对象本身的复杂性。
在这种情况下有效的另一个有趣示例:
ForeignKey('models')
如果两个列在两个表上的名称相同,则SQLAlchemy似乎从表中推断出该列。如果您在示例中更改了id_model
列定义中的任何一个的名称,以使它们的名称不同,则此方法将停止工作。另外,我还没有找到足够好的文档,而且它不够明确,因此不确定是否真的值得使用,是否只是出于完整性而提及,因为我发现它很有趣。关于column
arg:
ForeignKey._column_tokens()
中的注释似乎比文档更明确。
# 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.