4

这是调试器中的异常跟踪

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.

这是我的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)

我确实为事务表指定了一个外键,并在控制器表中指定了一个反向引用,但无法弄清楚我哪里出错了

这是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
    */

我究竟做错了什么?

编辑后按米格尔修改

    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)

我得到了这个例外

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.
4

1 回答 1

3

这应该教我正确地使用 RTFM 烧瓶在数据库表名中强制执行 CamelCase

在我从手册中弄清楚之前,我挠了两天的头。有人应该在该页面上使其粗体或突出或其他内容。

    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)

这是有效的代码,如果您使用 sqlacodegen 使您的 model.py 最初像我一样,如果您想使用tablename ,请不要忘记将 ' 转义为 '\

于 2013-10-18T16:48:52.900 回答