2016-11-18 4 views
0

でSQLAlchemyのを使用してクエリを実行する方法:「ユーザー」と次のように定義された「プロジェクト」:モデル2つのテーブルがありますID

create table user (
    id integer primary key autoincrement 
); 

create table project (
    id integer primary key autoincrement, 
    user_id integer 
); 

をそして第​​三に、テーブルは、プロジェクトのIDをユーザーにマッピングするために使用されます。

をPythonで
create table users_to_projects_table (
    user_id integer, 
    project_id integer 
); 

Iは、第1の関係のテーブルを宣言する:

users_to_projects_table = db.Table('users_to_projects_table', 
    db.Column('user_id', db.Integer, db.ForeignKey('user.id')), 
    db.Column('project_id', db.Integer, db.ForeignKey('project.id')) 
) 

そしてIはのクラスを作成することによって進行210とUserテーブル:

class User(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    projects = db.relationship('Project', backref='user', lazy='dynamic') 


class Project(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) 

    _users = db.relationship('User', secondary=users_to_projects_table, backref=db.backref('users_to_projects_backref', lazy='dynamic')) 

    @property 
    def users(self): 
     return self._users 

    @users.setter 
    def users(self, user_ids): 
     self._users = [User.query.filter_by(id=user_id).one() for user_id in user_ids] 

今それがすべて完了したとき、私は先に行くとuserを作成します。

user = User() 
db.session.add(user) 
db.session.commit() 

次の私は、引数としてそれをuser.idを渡すことによって、projectを作成します。

project = Project(users=[user.id]) 
db.session.add(project) 
db.session.commit() 

すべてがうまく見えます。 userprojectの両方がデータベースに書き込まれていることがわかります。そして、users_to_projects_tableは、project_idとそれに関連付けられたuser_idの両方で正しく更新されました。

質問:今すぐusers_to_projects_tableで「どのようなuser_idが「project_id」に対応しているか知っていますか?以下 コマンドはInvalidRequestErrorで失敗します。

project_id = 1 
User.projects.query.filter_by(project_id=project_id) 

エラーは以下の通りです:

InvalidRequestError: Entity '<class '_app.User'>' has no property 'project_id' 

ためそれを動作させるために変更する必要がありますか?

答えて

1

projectsの関係でsecondary=users_to_projects_tableを設定する必要があります。

可能なクエリはUser.query.filter(User.projects.any(id=project_id))ですが、おそらく結合を使用するほうがよいでしょう。

結合を使用して潜在的に速く(長いとはいえ)クエリ:

User.query.select_from(User).join(users_to_projects_table).join(Project).filter(Project.id==project_id 
+0

感謝を! 2番目のコマンドは、末尾に '.all()'を追加した後にうまくいきます: 'User.query.select_from(User).join(users_to_projects_table).join(Project).filter(Project.id == project_id).all() ' – alphanumeric

+0

あなたが提案した最初のコマンドも同様に機能します。 'projects = db.relationship( 'Project'、backref = 'user'、lazy = 'dynamic'、secondary = users_to_projects_table)' – alphanumeric

+0

これで、クエリーコマンドは 'User.query。フィルタ(User.projects.any(id = project_id))。all() 'もう一度ありがとう! – alphanumeric

関連する問題