2015-10-02 13 views
7

Tôi cần có một bài đăng liên quan đến hai người dùng. Tác giả và người kiểm duyệt. Tôi đang cố gắng nhưng không thành công mã nàyMột đối tượng hai khóa ngoài cùng một bảng

class User(UserMixin, db.Model): 
    __tablename__ = 'users' 
    id = db.Column(db.Integer, primary_key=True) 
    ... 
    post = db.relationship('Post', foreign_keys=['posts.id'], backref='post_user', lazy='dynamic') 
    post_blame = db.relationship('Post', foreign_keys=['posts.moderated_by'], backref='post_blame', lazy='dynamic')  

class Post(db.Model): 
    __tablename__ = 'posts' 
    id = db.Column(db.Integer, primary_key=True) 
    ... 
    author_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) 
    moderated_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) 

Lỗi:

ArgumentError: Column-based expression object expected for argument 'foreign_keys'; got: 'posts.id', type <type 's 
+1

Xin vui lòng gửi traceback lỗi đầy đủ. –

+2

Được giải quyết dựa trên chủ đề này https://www.reddit.com/r/flask/comments/2o4ejl/af_flask_sqlalchemy_two_foreign_keys_referencing/ – anvd

Trả lời

11

Một trong những vấn đề ở đây là bạn đang cố gắng sử dụng các cột bảng trong mối quan hệ foreign_keys, chứ không phải là thuộc tính lớp.

Tức là, thay vì sử dụng posts.id, bạn nên sử dụng Post.id. (Thực tế, để tham khảo cột bảng, bạn sẽ cần phải sử dụng posts.c.id).

Vì vậy, nó có thể là mã ban đầu của bạn sẽ có tác dụng nếu bạn khắc phục nó để:

class User(UserMixin, db.Model): 
    __tablename__ = 'users' 
    id = db.Column(db.Integer, primary_key=True) 
    ... 
    post = db.relationship('Post', foreign_keys='Post.id', backref='post_user', lazy='dynamic') 
    post_blame = db.relationship('Post', foreign_keys='Post.moderated_by', backref='post_blame', lazy='dynamic')  

Nếu không, sau đó có một vài lựa chọn khác. Đầu tiên, bạn có thể thiết lập các mối quan hệ này trong lớp Post, nơi mà nó ít mơ hồ hơn đối với sqlalchemy để tìm mối quan hệ khóa ngoại. Một cái gì đó như

class Post(db.Model): 
    __tablename__ = 'posts' 
    id = db.Column(db.Integer, primary_key=True) 
    ... 
    author_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) 
    moderated_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) 
    post_user = db.relationship(User, foreign_keys=author_id, backref='post', lazy='dynamic') 
    post_blame = db.relationship(User, foreign_keys=moderated_by, backref='post_blame', lazy='dynamic')  

Lưu ý trong phiên bản này, chúng tôi không cần phải vượt qua giá trị foreign_keys như là một chuỗi, chúng tôi chỉ có thể tham khảo trực tiếp đến cột trong phạm vi.

Ngoài ra, nếu bạn muốn thiết lập các mối quan hệ trong tài khoản, bạn có thể bạn cần phải cung cấp cho sqlalchemy biết thêm thông tin, bằng cách sử dụng primaryjoin ... có lẽ cái gì đó như:

class User(UserMixin, db.Model): 
    __tablename__ = 'users' 
    id = db.Column(db.Integer, primary_key=True) 
    ... 
    post = db.relationship('Post', primaryjoin='User.id == Post.id', backref='post_user', lazy='dynamic') 
    post_blame = db.relationship('Post', foreign_keys='User.id == Post.moderated_by', backref='post_blame', lazy='dynamic')  
+1

ví dụ đầu tiên, cùng một loại lỗi mà tôi đang nhận được (đối tượng biểu thức dựa trên cột được mong đợi cho đối số 'foreign_keys'). mối quan hệ ví dụ thứ hai() đã nhận được một đối số từ khóa không mong muốn 'primary_join' – anvd

+2

@anvd primary_join phải là tham gia chính. Cũng đã chỉ nhận thấy rằng bạn đang sử dụng tên bảng, không phải tên lớp trong 'external_keys' của bạn và tôi đã sửa đổi câu trả lời của tôi cho phù hợp. Cho tôi biết làm thế nào nó đi! – donkopotamus

+3

Tôi không thực sự quan tâm đến tiền thưởng của bạn, tôi cũng không đặc biệt quan tâm đến việc cố gắng sao chép hoàn toàn bảng và cấu trúc cơ sở dữ liệu của bạn để giúp bạn trong một vấn đề đơn giản hợp lý. Tôi chỉ cố gắng cung cấp con trỏ ... bạn biết đấy, tôi nghi ngờ bạn có thể ** có khả năng làm những việc như tra cứu tài liệu **. Ví dụ, một cái nhìn đơn giản về mối quan hệ api sẽ cho bạn biết rằng 'primary_join' có nghĩa là' primaryjoin' ... – donkopotamus

Các vấn đề liên quan