代码之家  ›  专栏  ›  技术社区  ›  not 0x12

SQL Alchemy PostgreSQL从ORM模式创建表时出错没有唯一键约束

  •  0
  • not 0x12  · 技术社区  · 5 年前

    我有一个作者书的简单模型,但我找不到一种方法来将firstName和lastName作为复合键,并在关系中使用它。有什么想法吗?

    from sqlalchemy import create_engine, ForeignKey, Column, String, Integer
    from sqlalchemy.orm import relationship, sessionmaker
    from sqlalchemy.ext.declarative import declarative_base
    
    Base = declarative_base()
    engine = create_engine('mssql://user:pass@library')
    engine.echo = True
    session = sessionmaker(engine)()
    
    class Author(Base):
        __tablename__ = 'authors'
        firstName = Column(String(20), primary_key=True)
        lastName = Column(String(20), primary_key=True)
        books = relationship('Book', backref='author')
    
    class Book(Base):
        __tablename__ = 'books'
        title = Column(String(20), primary_key=True)
        author_firstName = Column(String(20), ForeignKey('authors.firstName'))
        author_lastName = Column(String(20), ForeignKey('authors.lastName'))            
    
    0 回复  |  直到 10 年前
        1
  •  98
  •   SingleNegationElimination    13 年前

    问题是,您已经将每个依赖列分别定义为外键,当这不是您真正想要的时,您当然想要一个复合外键。Sqlalchemy对此的回应是(以一种不太明确的方式)它无法猜测使用哪个外键( firstName lastName ).

    声明复合外键的解决方案在声明性方面有点笨拙,但仍然相当明显:

    class Book(Base):
        __tablename__ = 'books'
        title = Column(String(20), primary_key=True)
        author_firstName = Column(String(20))
        author_lastName = Column(String(20))
        __table_args__ = (ForeignKeyConstraint([author_firstName, author_lastName],
                                               [Author.firstName, Author.lastName]),
                          {})
    

    重要的是 ForeignKey 定义从各个列中删除,并且 ForeignKeyConstraint 添加到 __table_args__ 类变量。有了这个 relationship 定义于 Author.books 工作正常。