【问题标题】:SQLALCHEMY: There is no unique constraint matching given keys for referenced tableSQLALCHEMY:引用表的给定键没有唯一约束匹配
【发布时间】:2016-04-13 13:12:09
【问题描述】:

我正在尝试在我的表卖家和商品之间建立一种关系,其中每个卖家都可以出售任意数量的商品,但他们不能两次出售相同的商品。这是我所拥有的:

sells = db.Table('sells',
     db.Column('seller_email', db.String(), db.ForeignKey('seller.email'), primary_key=True),
     db.Column('item_id', db.Integer, ForeignKey('item.id'), primary_key=True)
)

class Item(db.Model):
     __tablename__ = 'item'

     id = db.Column(db.Integer, primary_key=True)
     coverPhoto = db.Column(db.String())
     price = db.Column(db.Integer)
     condition = db.Column(db.Integer)
     title = db.Column(db.String())

     def __init__(self, title, coverPhoto, price, condition):
         self.coverPhoto = coverPhoto
         self.price = price
         self.condition = condition
         self.title = title

     def __repr__(self):
         return '<id {}>'.format(self.id)

class Seller(db.Model):
     __tablename__ = 'seller'

     email = db.Column(db.String(), primary_key=True)
     password = db.Column(db.String())
     firstName = db.Column(db.String())
     lastName = db.Column(db.String())
     location = db.Column(db.String())

     def __init__(self, email, password, firstName, lastName, location):
         self.email = email
         self.password = password
         self.firstName = firstName
         self.lastName = lastName
         self.location = location

     def __repr__(self):
         return "<Seller {email='%s'}>" % (self.email)

我收到以下错误:

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) there is no unique constraint matching given keys for referenced table "seller"

[SQL: '\nCREATE TABLE sells (\n\tseller_email VARCHAR NOT NULL, \n\titem_id INTEGER NOT NULL, \n\tPRIMARY KEY (seller_email, item_id), \n\tFOREIGN KEY(item_id) REFERENCES item (id), \n\tFOREIGN KEY(seller_email) REFERENCES seller (email)\n)\n\n']

Bother Seller.email 和 item.id 是主键,所以它们本身不应该是唯一的吗?

【问题讨论】:

  • 是的,主键本质上是唯一的。我不了解 SQLAlchemy,但在 SQL 数据库创建脚本中,关系表的定义需要遵循其他两个的定义。如果将sells = 部分移到脚本的末尾会有所不同吗?

标签: python sql postgresql flask sqlalchemy


【解决方案1】:

您正在使用 SQLAlchemy 核心函数 db.Table 创建表 sells。没有错。然后,通过使用 SQLAlchemy ORM 的声明性语法从 db.Model 继承来创建其他表。 (如果您不熟悉 SQLAlchemy Core 和 ORM 之间的区别,本教程是一个很好的起点。)

这里有几个潜在的问题:

  1. 您正在使用 db.Model 和 SQLAlchemy ORM 的声明性语法。当你这样做时,你的模型子类不需要__init__ 函数。事实上,使用__init__ 可能会导致问题(甚至可能是这里的根本原因),因为它会干扰 SQLAlchemy 为使声明式语法如此方便而进行的猴子补丁......

  2. 我怀疑这里的根本原因实际上可能是您使用 SQLAlchemy Core 创建了一个表,该表具有对 SQLAlchemy ORM 管理的表的外键引用。通常,当您执行db.metadata.create_all() 时,SQLAlchemy 将收集所有表/模型映射,查看依赖关系并找出将CREATE TABLE / ADD CONSTRAINT 命令发送到数据库的正确顺序。这种隐蔽的依赖关系解析允许应用程序程序员定义一个表,该表包含稍后定义的表的外键。当您有一个基于核心的 Table 对象引用基于 ORM db.Model 的对象时,它可能会阻止依赖关系解析在表创建期间正常工作。我不是 100% 确信这是问题所在,但值得尝试将所有表设为 Table 对象或 db.Model 子类。如果你不确定,我建议后者。

【讨论】:

  • flask-sqlalchemy.pocoo.org/2.1/models/… 他们的文档另有说明。他们建议将关系设为表格,并将其他所有内容建模。
  • 它当然可以工作,但要正确配置所有内容有点棘手,因为您必须更加注意何时使用 Core 与 ORM。由于您在模型类中使用了__init__,因此您似乎对 SQLAlchemy 的声明性语法并不熟悉,所以这就是为什么我建议对一个构造进行标准化直到您对它感到满意为止的部分原因。您是否在没有 __init__ 的情况下尝试过,看看是否解决了问题?
  • 你是我对 SQLAlchemy 不太熟悉。我遵循了本教程:realpython.com/blog/python/…,他们有__init__,所以我也将它添加到我的。我实际上是通过从上面的链接中复制代码来实现的。
  • 那么...这里有没有解决方案?如果是这样,它到底是什么?我看到这个答案被认为是正确的,但我不明白为什么。我们其他人可以在进入相同的兔子洞之前使用提示。
猜你喜欢
  • 2014-10-29
  • 2017-08-11
  • 1970-01-01
  • 2022-09-27
  • 2012-01-09
  • 2014-02-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多