SQLALCHEMY:没有唯一约束匹配引用表的给定键

时间:2016-01-08 18:51:21

标签: python sql postgresql flask sqlalchemy

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

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']

打扰卖家邮件和item.id是主键,所以它们本身不应该是唯一的吗?

1 个答案:

答案 0 :(得分:1)

您正在使用sells创建表db.Table,这是一个SQLAlchemy Core函数。没有错。然后通过使用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命令的正确顺序。这种无法解决的依赖项解析允许应用程序程序员定义一个表,该表包含稍后定义的表的外键。当您有一个基于Core的Table对象引用基于ORM db.Model的对象时,它可能会阻止依赖关系解析在表创建期间正常工作。我不是百分之百地确信这是问题所在,但值得尝试将所有表格设为Table个对象或db.Model个子类。如果你不确定,我建议后者。