SELECT
문의 근원지이다.Person.query.filter_by(name='Amy)
SELECT * FROM Person WHERE name = 'Amy';
과 동일Person.query.all()
SELECT * FROM Person;
Person.query.count()
Person.query.filter(Person.name == 'Amy')
.filter_by()
보다 더 flexible한 방법Person.query.filter(Person.name == 'Amy', Tema.name == 'Udacity')
Person.query.get(1)
Product.query.filter_by(category='Misc').delete()
bulk operation이란 large scale로 수행되는 action들을 말한다.
위의 코드는 카테고리가 'Misc'인 모든 레코드들을 한꺼번에 삭제한다.
MyModel.order_by(MyModel.created_at)
MyMode.order_by(db.desc(MyModel.created_at)) # db.desc: descending order
Order.query.limit(100).all() # limit(max_num_rows)
query
의 메소드들은 first()
나 all()
, count()
, delete()
처럼 non-query object를 리턴하는 terminal method를 사용하기 전까지는 무한으로 계속 엮일 수 있다.
Person.query.filter(Person.name == 'Amy').frist()
도 가능하고 Person.query.filter(Person.name == 'Amy').flter(Tema.name == 'Udacity').first()
도 가능하다. SQL문에서 여러개의 WHERE절이 함께 쓰이는 것과 같은 의미이다.
method chaining은 join이나 join을 해야할때 필수적이다.
Driver.query.join('vehicles').filter_by(driver_id=3).all()
는 Driver table과 Vehicle table을 조인하고 driver_id=3인 레코드들을 리턴한다.
Question. SQL에서는 조인할때 ON절이 필요하지만 여기서는 에트리뷰트 이름만 써준다. 그럼 기준키를 어떻게 하는걸까?
Consider a mapping between two classes
User
andAddress
, with a relationshipUser.addresses
representing a collection ofAddress
objects associated with eachUser
. The most common usage ofjoin()
is to create a JOIN along this relationship, using theUser.addresses
attribute as an indicator for how this should occur:
q = session.query(User).join(User.addresses)
내가 이해한 게 맞다면 SQL에서는 ON절을 사용해서 테이블끼리 연결이 되지만 query에서는 만약 ~SQL으로만 생각하다가 이렇게 이해하려니 뭔가 내가 잘 이해하고 있는건지 잘 모르겠다. 계속 읽어보니 addresses -> Address 이렇게 이름으로 찾아가는게 아닌가 싶다.~~ ==> 이 내용에 대해 멘토에게 물어보니 다음과 같은 대답을 얻었다.User
라는 테이블과 Address
라는 테이블이 있을 때, User
테이블 안에 user와 관련된 주소가 해당 에트리뷰트(addresses
) 내에 존재한다면 (Address
테이블의 주소에 들어간 내용과 같겠지) 자동적으로 ON user.id = address.user_id
처리가 된다. 또한 User
에서만 선택할 거라면 .join("addresses")
와 같이 클래스명을 제외하고 string name만 적어도 된다. ~
If it’s the prior then you can call it(attribute) whatever you want as long as the model is linked to it. --> relationship
Here are two models Driver and Vehicle, so if you want to join them together and access the data, it should look something like this:
class Driver(db.Model): __tablename__ = 'driver'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
ride = db.relationship('Vehicle')
class Vehicle(db.Model):
__tablename__ = 'vehicle'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
drivers = Driver.query.join(Vehicle).all()
for driver in drivers:
for ride in driver:
print(ride.name)
Model을 만들때 relationship()
을 통해 애트리뷰트와 클래스를 연결했었기 때문에 바로 join이 가능했던 것이었다. relationship이 무슨 의미인지 파악하고 나니 위의 Query API에 있는 설명이 이해가 되었다.
foriegn key가 설정된 경우에는 두 테이블 명을 적어서 join하면 된다. 설정하지 않은 채로 아래와 같이 실행한다면 오류가 난다.
q = session.query(User).join(Address)
Person.query
db.session.query(Person)
The reason why we might want to do it this way instead of using an individual model is that every once in ah while you may want to do a joint query instead. --> session.query(Person).join(Team)
So since session.query
is agnostic(=>~와 관계없는, 종속적이지 않은) to the type of model that you pass in, you can do things like session.query
of person.join
on another model Team.
--> 잘 이해가 안됨...
Let's say you created a Users tale with a name
attribute.
1. Implement a query to filter all users by name 'Bob'.
User.query.filter_by(name='Bob').all()
User.query.filter(User.name.like('%b%')).all()
User.query.limit(5).all()
User.query.filter(or_(User.name.like('%B%'), User.name.like('%b%'))).all()
User.query.filter_by(name='Bob').count()
session.rollback()
을 통해 undo가능INSERT
, UPDATE
, DELETE
관련 트랜잭션 발생Query
를 호출할 때Person.query
는 flush가 발생하지 않는다고 했는데 이것도 Query를 호출한 것 같은데 왜 flush가 일어나지 않는걸까?Person.query
는 object에 불과하다(Person.query()
처럼 사용할 수 없음). 강의에서는 설명이 부족했지만 Query
를 호출할 때는 BaseQuery에 사용 가능한 메소드(like .all()
)를 이용할 때를 의미한 것이다.db.session.commit()
--> flush & commit