简体   繁体   English

flask sqlalchemy.exc.NoForeignKeysError NoForeignKeysError:无法确定连接条件

[英]flask sqlalchemy.exc.NoForeignKeysError NoForeignKeysError: Could not determine join condition

Here is the exception trace in the debugger 这是调试器中的异常跟踪

sqlalchemy.exc.NoForeignKeysError

NoForeignKeysError: Could not determine join condition between parent/child tables on relationship Department.employees - there are no foreign keys linking these tables. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify a 'primaryjoin' expression.

This is my models.py, I'm using reflection with an existing schema. 这是我的models.py,我在现有模式中使用反射。

    from sqlalchemy import Table, Column, Integer, ForeignKey, String, DateTime, Date, Time
    from sqlalchemy.orm import relationship, backref

    #make sure we get the right base
    from database import ProbeDB_Base, DB

    class Location(ProbeDB_Base):
        __tablename__ = u'Location'
        __table_args__ = {u'schema': u'probedb'}

        LocationID = Column(Integer, primary_key=True)
        LocationName = Column(String(100))
        controllers = relationship("Controller", backref="Location")

    class Controller(ProbeDB_Base):
        __tablename__ = u'Controller'
        __table_args__ = {u'schema': 'probedb'}

        ControllerID = Column(Integer, primary_key=True)
        ControllerName = Column(String(100))
        ControllerNo = Column(Integer)
        SlaveNo = Column(Integer)
        IPAddress = Column(String(20))
        Port = Column(Integer)
        CommunicationType = Column(Integer)
        Enable = Column(Integer)
        ResponseTime = Column(Integer)
        LocationID = Column(Integer, ForeignKey('Location.LocationID'), index=True)
        #LocationID = relationship(Location, primaryjoin='Controller.LocationID == DB.Location.LocationID')
        MaxChannels = Column(Integer)
        #Location_id = relationship(u'Location')
        transactions = relationship("Transaction", backref="Controller")

    class Department(ProbeDB_Base):
        __tablename__ = u'Department'
        __table_args__ = {u'schema': 'probedb'}

        DepartmentID = Column(Integer, primary_key=True)
        Name = Column(String(100))
        employees = relationship("Employee", backref="Department")

    class Designation(ProbeDB_Base):
        __tablename__ = u'Designation'
        __table_args__ = {u'schema': 'probedb'}

        DesignationID = Column(Integer, primary_key=True)
        Name = Column(String(100))
        employees = relationship("Employee", backref="Designation")

    class Employee(ProbeDB_Base):
        __tablename__ = u'Employee'
        __table_args__ = {u'schema': 'probedb'}

        EmployeeID = Column(Integer, primary_key=True)
        EmployeeCode = Column(String(15), index=True)
        LocationID = Column(Integer)
        Name = Column(String(50))
        CardNo = Column(Integer)
        DepartmentID = Column(Integer, ForeignKey('Department.DepartmentID'), index=True)
        #DepartmentID = relationship(Department, primaryjoin='Employee.DepartmentID == DB.Department.DepartmentID')
        DesignationID = Column(Integer, ForeignKey('Designation.DesignationID'), index=True)
        #DesignationID = relationship(Designation, primaryjoin='Employee.DesignationID == DB.Designation.DesignationID')
        EnrollDate = Column(DateTime)
        ExpDate = Column(DateTime)
        #Department_id = relationship(u'Department')
        #Designation_id = relationship(u'Designation')

    class Event(ProbeDB_Base):
        __tablename__ = u'Event'
        __table_args__ = {u'schema': 'probedb'}

        EventID = Column(Integer, primary_key=True)
        Name = Column(String(100))

        transactions = relationship("Transaction", backref="Event")

    class Transaction(ProbeDB_Base):
        __tablename__ = u'Transaction'
        __table_args__ = {u'schema': 'probedb'}

        TransactionID = Column(Integer, primary_key=True)
        DateTime = Column(DateTime)
        Date = Column(Date)
        Time = Column(Time)
        CardNo = Column(Integer)
        Channel = Column(Integer)
        EventID = Column(Integer, ForeignKey('Event.EventID'), index=True)
        #EventID = relationship(Event, primaryjoin='Transaction.EventID == DB.Event.EventID')
        AccessType = Column(String(4))
        ReadPtr = Column(Integer)
        ControllerID = Column(Integer, ForeignKey('Controller.ControllerID'), index=True)
        #ControllerID = relationship("Controller", primaryjoin='Transaction.ControllerID == Controller.ControllerID')
        IPAddress = Column(String(20))
        #Controller_id = relationship(u'Controller')
        #Event_id = relationship(u'Event')

    class User(ProbeDB_Base):
        __tablename__ = u'users'
        __table_args__ = {u'schema': 'probedb'}

        uid = Column(Integer, primary_key=True)
        firstname = Column(String(100), nullable=False)
        lastname = Column(String(100), nullable=False)
        email = Column(String(120), nullable=False, index=True)
        pwdhash = Column(String(100), nullable=False)

I did specify a foreign key for the transaction table and a backref in the controller table, but not able to figure out where I am going wrong 我确实为事务表和控制器表中的外引用指定了一个外键,但无法弄清楚我要去哪里

Here is the create.sql for the table 这是表的create.sql

    /*
    ProbeDB 
    This is the setup SQL for probedb
    */

    CREATE TABLE IF NOT EXISTS Location(
    LocationID int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    LocationName varchar(100)
    )
    ;
    CREATE TABLE IF NOT EXISTS Controller(
    ControllerID int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ControllerName varchar(100),
    ControllerNo int,
    SlaveNo int,
    CONSTRAINT SlaveNo_Ck CHECK (SlaveNo BETWEEN 1 AND 128),
    IPAddress varchar(20),
    Port int,
    CommunicationType int,
    CONSTRAINT CommunicationType_Ck CHECK (CommunicationType BETWEEN 1 AND 2),
    /* 
    1 TCP
    2 UDP
    */
    Enable int, 
    CONSTRAINT Enable_Ck CHECK (Enable BETWEEN 0 AND 1),
    /* 
    0 Enable
    1 Disable
    */
    ResponseTime int,
    LocationID int,
    CONSTRAINT fk_LocationReference FOREIGN KEY (LocationID) REFERENCES Location(LocationID),
    MaxChannels int
    )
    ;
    CREATE TABLE IF NOT EXISTS Department(
    DepartmentID int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    Name varchar(100)
    )
    ;
    CREATE TABLE IF NOT EXISTS Designation(
    DesignationID int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    Name varchar(100)
    )
    ;
    CREATE TABLE IF NOT EXISTS Employee(
    EmployeeID int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    EmployeeCode varchar(15) UNIQUE,
    LocationID int,
    Name varchar(50),
    CardNo int,
    DepartmentID int,
    CONSTRAINT fk_DepartmentReference FOREIGN KEY (DepartmentID) REFERENCES Department(DepartmentID),
    DesignationID int,
    CONSTRAINT fk_DesignationReference FOREIGN KEY (DesignationID) REFERENCES Designation(DesignationID),
    EnrollDate datetime,
    ExpDate datetime
    )
    ;
    CREATE TABLE IF NOT EXISTS Event(
    EventID int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    Name varchar(100)
    )
    ;
    CREATE TABLE IF NOT EXISTS Transaction(
    TransactionID int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    DateTime datetime,
    Date date,
    Time time,
    CardNo int,
    Channel int,
    EventID int,
    CONSTRAINT fk_EventReference FOREIGN KEY (EventID) REFERENCES Event(EventID),
    AccessType varchar(4),
    ReadPtr int,
    ControllerID int,
    CONSTRAINT fk_ControllerReference FOREIGN KEY (ControllerID) REFERENCES Controller(ControllerID),
    IPAddress varchar(20)
    )
    ;
    CREATE TABLE users (
    uid INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    firstname VARCHAR(100) NOT NULL,
    lastname VARCHAR(100) NOT NULL,
    email VARCHAR(120) NOT NULL UNIQUE,
    pwdhash VARCHAR(100) NOT NULL
    );
    /*
    END
    */

What am I doing wrong? 我究竟做错了什么?

EDITED After modifying per Miguel 根据Miguel修改后编辑

    from sqlalchemy import Table, Column, Integer, ForeignKey, String, DateTime, Date, Time
    from sqlalchemy.orm import relationship, backref

    #make sure we get the right base
    from database import ProbeDB_Base, DB

    class Location(ProbeDB_Base):
        __tablename__ = u'Location'
        __table_args__ = {u'schema': u'probedb'}

        LocationID = Column(Integer, primary_key=True)
        LocationName = Column(String(100))
        controllers = relationship("Controller", backref="Location")

    class Controller(ProbeDB_Base):
        __tablename__ = u'Controller'
        __table_args__ = {u'schema': 'probedb'}

        ControllerID = Column(Integer, primary_key=True)
        ControllerName = Column(String(100))
        ControllerNo = Column(Integer)
        SlaveNo = Column(Integer)
        IPAddress = Column(String(20))
        Port = Column(Integer)
        CommunicationType = Column(Integer)
        Enable = Column(Integer)
        ResponseTime = Column(Integer)
        LocationID = Column(Integer, ForeignKey('Location'), index=True)
        #LocationID = relationship(Location, primaryjoin='Controller.LocationID == DB.Location.LocationID')
        MaxChannels = Column(Integer)
        #Location_id = relationship(u'Location')
        transactions = relationship("Transaction", backref="Controller")

    class Department(ProbeDB_Base):
        __tablename__ = u'Department'
        __table_args__ = {u'schema': 'probedb'}

        DepartmentID = Column(Integer, primary_key=True)
        Name = Column(String(100))
        employees = relationship("Employee", backref="Department")

    class Designation(ProbeDB_Base):
        __tablename__ = u'Designation'
        __table_args__ = {u'schema': 'probedb'}

        DesignationID = Column(Integer, primary_key=True)
        Name = Column(String(100))
        employees = relationship("Employee", backref="Designation")

    class Employee(ProbeDB_Base):
        __tablename__ = u'Employee'
        __table_args__ = {u'schema': 'probedb'}

        EmployeeID = Column(Integer, primary_key=True)
        EmployeeCode = Column(String(15), index=True)
        LocationID = Column(Integer)
        Name = Column(String(50))
        CardNo = Column(Integer)
        DepartmentID = Column(Integer, ForeignKey('Department'), index=True)
        #DepartmentID = relationship(Department, primaryjoin='Employee.DepartmentID == DB.Department.DepartmentID')
        DesignationID = Column(Integer, ForeignKey('Designation'), index=True)
        #DesignationID = relationship(Designation, primaryjoin='Employee.DesignationID == DB.Designation.DesignationID')
        EnrollDate = Column(DateTime)
        ExpDate = Column(DateTime)
        #Department_id = relationship(u'Department')
        #Designation_id = relationship(u'Designation')

    class Event(ProbeDB_Base):
        __tablename__ = u'Event'
        __table_args__ = {u'schema': 'probedb'}

        EventID = Column(Integer, primary_key=True)
        Name = Column(String(100))

        transactions = relationship("Transaction", backref="Event")

    class Transaction(ProbeDB_Base):
        __tablename__ = u'Transaction'
        __table_args__ = {u'schema': 'probedb'}

        TransactionID = Column(Integer, primary_key=True)
        DateTime = Column(DateTime)
        Date = Column(Date)
        Time = Column(Time)
        CardNo = Column(Integer)
        Channel = Column(Integer)
        EventID = Column(Integer, ForeignKey('Event'), index=True)
        #EventID = relationship(Event, primaryjoin='Transaction.EventID == DB.Event.EventID')
        AccessType = Column(String(4))
        ReadPtr = Column(Integer)
        ControllerID = Column(Integer, ForeignKey('Controller'), index=True)
        #ControllerID = relationship("Controller", primaryjoin='Transaction.ControllerID == Controller.ControllerID')
        IPAddress = Column(String(20))
        #Controller_id = relationship(u'Controller')
        #Event_id = relationship(u'Event')

    class User(ProbeDB_Base):
        __tablename__ = u'users'
        __table_args__ = {u'schema': 'probedb'}

        uid = Column(Integer, primary_key=True)
        firstname = Column(String(100), nullable=False)
        lastname = Column(String(100), nullable=False)
        email = Column(String(120), nullable=False, index=True)
        pwdhash = Column(String(100), nullable=False)

I get this exception 我得到这个例外

sqlalchemy.exc.NoForeignKeysError

NoForeignKeysError: Could not determine join condition between parent/child tables on relationship Designation.employees - there are no foreign keys linking these tables. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify a 'primaryjoin' expression.

This should teach me to RTFM properly flask enforces CamelCase in database tablenames 这应该教会我正确的RTFM烧瓶在数据库表名中强制执行CamelCase

Scratched my head for two days before I figured it out from the manual . 在我从手册中找到头之前,我挠头呆了两天。 Someone should make it bold or make it stand out or something on that page. 有人应该将其加粗或使其突出或在页面上显示某些内容。

    from sqlalchemy import Table, Column, Integer, ForeignKey, String, DateTime, Date, Time
    from sqlalchemy.orm import relationship, backref
    from database import ProbeDB_Base, DB

    #make sure your models are setup right for reflection of an existing schema
    #convert all CamelCase table names - if you SQL table name is MyName, then change it to my_name
    #make sure you add backrefs and primaryjoin relationships for each ForeignKey constraint
    #make sure you escape all ' like this - \' in your relationship statements

    class Location(ProbeDB_Base):
        __tablename__ = u'location'
        __table_args__ = {u'schema': u'probedb'}

        location_id = Column(Integer, primary_key=True)
        Locationname = Column(String(100))
        controllers = relationship("u'controller'", backref="u'location'")

    class Controller(ProbeDB_Base):
        __tablename__ = u'lontroller'
        __table_args__ = {u'schema': 'probedb'}

        controller_id = Column(Integer, primary_key=True)
        controller_name = Column(String(100))
        controller_no = Column(Integer)
        slave_no = Column(Integer)
        ip_address = Column(String(20))
        port = Column(Integer)
        communicationType = Column(Integer)
        enable = Column(Integer)
        responseTime = Column(Integer)
        #location_id = Column(Integer, ForeignKey('location.location_id'), index=True)
        location_id = relationship(Location, primaryjoin='u\'controller\'.location_id == u\'location\'.location_id')
        max_channels = Column(Integer)
        #Location_id = relationship(u'Location')
        transactions = relationship("u'transaction'", backref="u'controller'")


    class Department(ProbeDB_Base):
        __tablename__ = u'department'
        __table_args__ = {u'schema': 'probedb'}

        department_id = Column(Integer, primary_key=True)
        name = Column(String(100))
        employees = relationship("u'employee'", backref="u'department'")

    class Designation(ProbeDB_Base):
        __tablename__ = u'designation'
        __table_args__ = {u'schema': 'probedb'}

        designation_id = Column(Integer, primary_key=True)
        name = Column(String(100))
        employees = relationship("u'employee'", backref="u'designation'")

    class Employee(ProbeDB_Base):
        __tablename__ = u'employee'
        __table_args__ = {u'schema': 'probedb'}

        employee_id = Column(Integer, primary_key=True)
        employee_code = Column(String(15), index=True)
        location_id = Column(Integer)
        name = Column(String(50))
        CardNo = Column(Integer)
        #department_id = Column(Integer, ForeignKey('Department.department_id'), index=True)
        department_id = relationship(u'department', primaryjoin='u\'employee\'.department_id == u\'department\'.department_id')
        #designation_id = Column(Integer, ForeignKey('Designation.designation_id'), index=True)
        designation_id = relationship(u'designation', primaryjoin='u\'employee\'.designation_id == u\'designation\'.designation_id')
        enroll_date = Column(DateTime)
        exp_date = Column(DateTime)
        #department_id = relationship(u'department')
        #designation_id = relationship(u'designation')

    class Event(ProbeDB_Base):
        __tablename__ = u'event'
        __table_args__ = {u'schema': 'probedb'}

        event_id = Column(Integer, primary_key=True)
        name = Column(String(100))

        transactions = relationship("u'transaction'", backref="u'event'")

    class Transaction(ProbeDB_Base):
        __tablename__ = u'transaction'
        __table_args__ = {u'schema': 'probedb'}

        transaction_id = Column(Integer, primary_key=True)
        date_time = Column(DateTime)
        date = Column(Date)
        time = Column(Time)
        card_no = Column(Integer)
        channel = Column(Integer)
        #event_id = Column(Integer, ForeignKey('event.event_id'), index=True)
        event_id = relationship(u'event', primaryjoin='u\'transaction\'.event_id == u\'event\'.event_id')
        accessType = Column(String(4))
        read_ptr = Column(Integer)
        #controller_id = Column(Integer, ForeignKey(controller.controller_id'), index=True)
        controller_id = relationship(u'controller', primaryjoin='u\'transaction\'.controller_id == u\'controller\'.controller_id')
        ip_address = Column(String(20))
        #Controller_id = relationship(u'Controller')
        #Event_id = relationship(u'Event')

    class User(ProbeDB_Base):
        __tablename__ = u'users'
        __table_args__ = {u'schema': 'probedb'}

        uid = Column(Integer, primary_key=True)
        firstname = Column(String(100), nullable=False)
        lastname = Column(String(100), nullable=False)
        email = Column(String(120), nullable=False, index=True)
        pwdhash = Column(String(100), nullable=False)

This is the code that works, and if you used sqlacodegen to make your model.py initially like me, don't forget to escape ' to '\\ if you want to use tablename 这是有效的代码,如果您最初使用sqlacodegen来创建model.py,就像我一样,如果要使用表名 ,请不要忘记将'换成'\\

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM