2012-02-28 6 views
14

우리는 Python 코드를 형식화하고 한 줄에 80 자 미만으로 유지하기 위해 PEP8 지침을 따르려고합니다.SQLAlchemy 코드 서식 지정

SQLAlchemy의 SQLAlchemy 라인은 여러 가지 복잡한 메소드, 수많은 복잡한 매개 변수, 논리 및 중첩 함수를 가지고있어 특히 문제가 있습니다.

PEP8의 제약 조건으로 Python SQLAlchemy를 포맷하는 특별한 모범 사례가 있습니까?

내가 찾은 가장 가까운 대답은 here이지만, 다루는 코드는 훨씬 복잡합니다.

답변

7

pep-8은 백 슬래시를 사용하지 않지만 SQLAlchemy 코드의 경우 각 행의 시작 부분에 각 생성 함수를 유지할 수 있으므로 가장 쉽게 읽을 수 있다고 생각합니다. 괄호 안에 여러 개의 인수가있는 경우 개별 줄에서도 나눕니다. 코드가 얼마나 복잡한 문제가되지 않습니다 물론

subkeyword = Session.query(
        Subkeyword.subkeyword_id, 
        Subkeyword.subkeyword_word 
      ).\ 
       filter_by(subkeyword_company_id=self.e_company_id).\ 
       filter_by(subkeyword_word=subkeyword_word).\ 
       filter_by(subkeyword_active=True).\ 
       one() 

그것은, 요철 무늬는 그러나 파이썬에서 우리는 과도한 중첩을 피하려고, 코드의 양에 수행 할 수있다. 일반적으로 쿼리를 사용하면 많은 하위 쿼리를 함께 구성하기 때문에 중첩이 발생합니다. 따라서 하위 쿼리를 미리 생성하십시오.

subq = Session.query(
       Bat.id, 
       func.foo(Bat.x, Bat.y).label('foo') 
       ).\ 
       filter(Bat.id==Bar.name).\ 
       correlate(Bar).\ 
       subquery() 

subq2 = Session.query(Foo.id, Foo.bar).\ 
       filter_by(flag>5).\ 
       subquery() 

result = Session.query(
        subq.c.id, 
        subq.c.foo, 
        subq2.c.bar 
       ).\ 
       join(subq2, 
        and_(
         subq.c.id > subq2.c.foo, 
         subq.bar == subq2.id 
        ) 
       ).\ 
       order_by(subq.c.id, subq2.c.bar) 

백 슬래시에 대한 다른 의견을 환영합니다.

+2

좋은 백 슬래시 사용 http://www.pocoo.org/internal/styleguide/ – estin

1

그래, 이것들은 당신이하는 일에 상관없이 불쾌 할 것입니다. 그래서이 구조들을 더 짧은 줄로 나눌 수있을 정도로 확실히 그렇게 할 수 있습니다.

할 수 없으면 전체 RHS를 괄호로 묶어 모든 백 슬래시를 제거 할 수 있습니다. 파이썬은 백 슬래시를 사용하지 않고 멀티 라인 구문을 적절히 구문 분석 할 것입니다. 그러나 이것이 더 낫지는 않은지 말하기 어렵습니다. 이와 같은 경우, 최선의 판단을 사용하고 코를 들고 뛰어 들어야한다고 생각합니다.

+1

pep8의 가능성은 말 그대로, "이 백 슬래시를 사용에 우선하여 사용되어야한다 백 슬래시 (대한 명확되고 있는지 라인 연속을 위해. "유일한 언급입니까)? 그들이 낙심한다면, 왜 파이썬이 그것들을 가지고 있습니까? – zzzeek

2

저는 zzzeek이 대답 한 것과 비슷한 방식으로 백 슬래시를 자주 사용합니다. PEP8은 지침 일 뿐이며 위반할 때 잠을 자지 않습니다!

그러나 나는 또한 자주 나는 zzzeek의 첫 번째 예를 도난 한 경우, 아래 서식의 형식을 사용, 약간을 쥐게하고 포맷 :

q = Session.query(
    Subkeyword.subkeyword_id, 
    Subkeyword.subkeyword_word, 
) 
q = q.filter_by(subkeyword_company_id=self.e_company_id) # first filter 
q = q.filter_by(subkeyword_word=subkeyword_word) # 2nd filter 
q = q.filter_by(subkeyword_active=True) 

if filter_by_foo: 
    q = q.filter(Subkeyword.foo == True) 

# Run the query (I usually wrap in a try block)... 
subkeyword = q.one() 

질문에 반복 된 재 할당 처음에 가지 불쾌한 것 , 그러나 나는 그것을 극복했다. 성능 영향은 사실상 유효하지 않습니다. 이 방법의 큰 장점은 후행 주석과 주석 행을 모두 섞어 쿼리를 문서화 할 수 있다는 것입니다 (위의 쓸모없는 추가로 수행 한 것처럼). 백 슬래시가있는 행을 연결하면 여기가 제한됩니다. 다른 예로서 등

로직 트리거 변형 톤 내장형 스칼라 선택과 대량 질의를 공식화 때

포맷팅이 방법은 고순도이며, I는 CTE 쿼리 I 상당히 큰 (> 150 라인)가 두 가지 방법을 혼합 한 혼합 논리, 에일리어싱 및 라벨링 (생성 된 쿼리의 가독성을 위해 필수적)이 많은 SQLAlchemy를 생성합니다.당신은 (않는 많은 일반 SQL 형식 체계와 같은) 새로운 작업으로 라인을 이끌 수 있는지 확인하는 경우, 그것은 유지, 일반적으로

cte_init = session.\ 
    query(
     child1.foo.label("child1_foo"), 
     sa.literal(1).label("indent"), # can comment on non-slashed lines 
     child2.bar.label("child2bar"), 
     #comments between non-slashed lines ok, too 
     sa.func.MAX(toplevel.baz).label("max_baz"), 
    ).\ 
    select_from(top_level).\ 
    join(child1, 
     child1.id == toplevel.fk_child1_id).\ 
    join(child2. 
     child2.id == toplevel.fk_child2.id).\ 
    filter(top_level.name == "bogus").\ 
    cte(name = "cte", recursive = True) 

if(use_filter_x): 
    cte_init = cte_init.filter_by(x = "whatever") 

# etc (no, the above doesn't make any sense)... 

: 그것의 심각한 감소 (및 난도질) 버전은 뭔가 아래와 같이 시작 꽤 읽을 수 있습니다. 괄호 안의 개줄도 두려워하지 마십시오.

+1

이것은 또한'pdb' a * lot *로 디버깅을 쉽게 할 수 있다는 장점이 있습니다! 각 필터가 자신의 성명서가됩니다! – exhuma

24

더 나은 솔루션을 기대 왔어요,하지만 난 괄호 배치 스타일을 선호 생각 :

subkeyword = (
    Session.query(
     Subkeyword.subkeyword_id, 
     Subkeyword.subkeyword_word 
    ) 
    .filter_by(subkeyword_company_id=self.e_company_id) 
    .filter_by(subkeyword_word=subkeyword_word) 
    .filter_by(subkeyword_active=True) 
    .one() 
) 

이 좋은 분명하다, 그리고 지칠대로 지친 백 슬래시를 피할 수 있습니다. pocoo 팀 스타일 가이드에