与列“ x.y”关联的外键无法...生成目标列“ None”的外键

时间:2018-11-17 11:08:19

标签: python sqlalchemy

我正在使用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'.

有什么办法解决这个问题吗?

1 个答案:

答案 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.