2013-07-23 3 views
4

쿼리에서 필터를 사용하려고했지만 어떤 이유로 필터링이 작동하지 않는 것 같습니다. 내가 명령을 실행하는 경우 예를 들어, :SQLAlchemy 필터링이 작동하지 않습니다.

Curriculum_Version.query.filter(Course.course_code == 'FEWD-001').all() 

(모두 반환) :

Curriculum_Version.query.filter(Course.course_code == 'PIP-001').all() 

을 내가 실행하는 것처럼 나도 같은 결과를 얻을 수

[#1 Version Number: 1, Date Implemented: 2013-07-23 00:00:00, #2 Version Number: 2, Date Implemented: 2013-07-24 00:00:00] 

내가 실행하는 경우 :

Curriculum_Version.query.get(1).course 

다음과 같이 표시됩니다.

01 내가 Curriculum_Versions에 대한 DB의 항목 작성하고있어 어떻게 23,516,
from main import app, db 
from flask import Flask, request, g, redirect, url_for 
from flaskext.auth import Auth, AuthUser, login_required, get_current_user_data 
from flaskext.auth.models.sa import get_user_class 
import datetime 
from flask.ext.sqlalchemy import SQLAlchemy 
import pdb 


class User(db.Model, AuthUser): 
    __tablename__ = 'users' 
    id = db.Column(db.Integer, primary_key=True) 
    tf_login = db.Column(db.String(255), unique=True, nullable=False) # can assume is an email 
    password = db.Column(db.String(120), nullable=False) 
    salt = db.Column(db.String(80)) 
    role = db.Column(db.String(80)) # for later when have different permission types 
    zoho_contactid = db.Column(db.String(20), unique=True, nullable=False) 
    created_asof = db.Column(db.DateTime, default=datetime.datetime.utcnow) 
    firstname = db.Column(db.String(80)) 
    lastname = db.Column(db.String(80)) 

    def __init__(self, zoho_contactid, firstname, lastname, tf_login, password, role, *args, **kwargs): 
     super(User, self).__init__(tf_login=tf_login, password=password, *args, **kwargs) 
     if (password is not None) and (not self.id): 
      self.created_asof = datetime.datetime.utcnow() 
      # Initialize and encrypt password before first save. 
      self.set_and_encrypt_password(password) 
     self.zoho_contactid = zoho_contactid # TODO 
     self.firstname = firstname 
     self.lastname = lastname 
     self.tf_login = tf_login # TODO -- change to tf_login 
     self.role = role 

    def __repr__(self): 
     return '#%d tf_login: %s, First Name: %s Last Name: %s created_asof %s' % (self.id, self.tf_login, self.firstname, self.lastname, self.created_asof) 

    def __getstate__(self): 
     return { 
      'id': self.id, 
      'tf_login': self.tf_login, 
      'firstname': self.firstname, 
      'lastname': self.lastname, 
      'role': self.role, 
      'created_asof': self.created_asof, 
     } 

    def __eq__(self, o): 
     return o.id == self.id 

    @classmethod 
    def load_current_user(cls, apply_timeout=True): 
     data = get_current_user_data(apply_timeout) 
     if not data: 
      return None 
     return cls.query.filter(cls.email == data['email']).one() 


class Enrollment(db.Model, AuthUser): 
    __tablename__ = 'enrollments' 
    id = db.Column(db.Integer, primary_key=True) 
    user_id = db.Column(db.Integer, db.ForeignKey('users.id')) 
    user = db.relationship('User', backref='enrollments') 
    curriculum_version_id = db.Column(db.Integer, db.ForeignKey('curriculum_versions.id')) 
    curriculumversion = db.relationship('Curriculum_Version', backref='enrollments') 
    cohort_id = db.Column(db.Integer, db.ForeignKey('cohorts.id')) 
    cohort = db.relationship('Cohort', backref='enrollments') 

    def __repr__(self): 
     return '#%d User ID: %s Version ID: %s, Cohort ID: %s' % (self.id, self.user_id, self.curriculum_version_id, self.cohort_id) 


class Cohort(db.Model, AuthUser): 
    __tablename__ = 'cohorts' 
    id = db.Column(db.Integer, primary_key=True) 
    start_date = db.Column(db.DateTime) 
    course_id = db.Column(db.Integer, db.ForeignKey('courses.id')) 
    course = db.relationship('Course', backref='cohorts') 

    def __repr__(self): 
     return '#%d Start Date: %s, Course: %s' % (self.id, self.start_date, self.course.course_code) 


class Curriculum_Version(db.Model, AuthUser): 
    __tablename__ = 'curriculum_versions' 
    id = db.Column(db.Integer, primary_key=True) 
    version_number = db.Column(db.String(6)) 
    date_implemented = db.Column(db.DateTime) 
    course_id = db.Column(db.Integer, db.ForeignKey('courses.id')) 
    course = db.relationship('Course', backref='curriculum_versions') 

    def __repr__(self): 
     return '#%d Version Number: %s, Date Implemented: %s' % (self.id, self.version_number, self.date_implemented) 


class Course(db.Model, AuthUser): 
    __tablename__ = 'courses' 
    id = db.Column(db.Integer, primary_key=True) 
    course_code = db.Column(db.String(20)) 
    course_name = db.Column(db.String(50)) 

    def __repr__(self): 
     return '#%d Course Code: %s, Course Name: %s' % (self.id, self.course_code, self.course_name) 

    def __eq__(self, o): 
     return o.id == self.id 

:

def update_courses(): 
    course_code = request.form['course_code'] 
    start_date = request.form['start_date'] 
    course_date = datetime.strptime(start_date, '%m/%d/%Y') 
    curr_version = Curriculum_Version.query.filter(Course.course_code == course_code) \ 
     .order_by(desc('version_number')).first() 

    if curr_version is None: 
     next_version = 1 
    else: 
     next_version = int(curr_version.version_number)+1 

    existing = Curriculum_Version.query.filter(Course.course_code == course_code) \ 
     .filter(Curriculum_Version.date_implemented == course_date) 

    if len(existing.all()) > 0: 
     return "You tried to make version %d of the curriculum, but version \ 
     %s of the curriculum already exists for %s for class %s." \ 
     %(next_version, existing.first().version_number, start_date, course_code) 

    course_object = Course.query.filter(Course.course_code == course_code).first() 

    if course_object is None: 
     return "The course %s does not yet exist!" % (course_code) 

    new_version = Curriculum_Version(version_number=next_version, date_implemented=course_date, course=course_object) 
    db.session.add(new_version) 
    db.session.commit() 
    return 'Created version %d for course %s starting on %s.' \ 
      %(next_version, course_code, start_date) 

답변

2

내가 필터링 사용하기 전에 가입 할 필요가 있다고 생각 하나의 쿼리 :

그렇지 않으면 sqlalchemy 필터링 전에 관계를 사용하는 것을 알 수 없습니다. 그냥 필터를 지정하는 경우

는 SQLAlchemy의는 조인을 수행 할 모르고 당신이에 SQL과 유사한 끝낼 : 많은 이해하지만 유효한 SQL하지 않는

SELECT curriculum_versions.* FROM curriculum_versions, courses WHERE 
    courses.course_code = "PIP-001" 

. SQLAlchemy의 당신이 query.join()Curriculum_Version.course를 전달하기 때문에 조건을 curriculum_versions.course_id = courses.id 을 사용하는 알고 당신이로 Curriculum_Version 클래스에 그 관계를 지정한

SELECT curriculum_versions.* FROM curriculum_versions JOIN courses ON 
    curriculum_versions.course_id = courses.id WHERE courses.course_code = "PIP-001" 

참고 : 사용할 때는이 같은 올바른 테이블에 대해 필터를 활용하여 가입 course 속성은 열에 지정해야하는 curriculum_versionscourses 테이블간에 사용할 수있는 유일한 외래 키를 자동으로 사용합니다.

당신은에 대한 자세한 내용을보실 수 있습니다 여기에 조인 http://docs.sqlalchemy.org/en/rel_0_7/orm/tutorial.html#querying-with-joins

+0

완벽하게 작동했습니다. 정말 고맙습니다! –

+0

잠시 시간이 있으면 왜 조인이 필요한지와 그것이 조인 관계를 어떻게 정의하는지 더 설명 할 수 있습니까? –

+0

나는 그것을 이해하는 한 설명을 확장하려고 노력했다. SQLAlchemy에 "옳은 일"을 수행하기에 충분한 정보를 제공하는지 여부를 결정하는 것이 중요하기 때문에 쿼리를 인쇄하고 SQL을 볼 수도 있습니다. 'first()'또는'all()'을 호출하기 전에 쿼리 객체를 명시 적으로 인쇄하거나 sqlalchemy의 echo 플래그를 켜서 모든 쿼리를 기록하도록 할 수 있습니다. –

2
다음과 같이 조회 할 수 있습니다

:

course_id = Course.query.filter(course_code="PIP-001").first().id 
curriculum = Curriculum_Version.query.filter(course_id=course_id).all() 
+0

을 나는 아직도 코드 "PIP-001"과 과정과 연관되지 않은 교육 과정의 버전을 받고 있어요 –

+0

"Curriculum_Version"외래 키가 올바르게 저장되고 있습니까? –

+0

@codegeek : +1,하지만 첫 줄은'first() .id '대신'first() .id'로 끝나야합니다.) .course_id'. – Miguel

1

내가 조립 한이 데모 애플리케이션을 살펴. 그것은 하나의 페이지 플라스크 & SQLAlchemy의 응용 프로그램, 그리고 나는 당신이 필요합니다 모든 것을 설명 생각 :

https://github.com/Thinkful/sqlalchemy-demo

관련 문제