2016-10-10 16 views
4

저는 파이썬 프로젝트에서 ORM으로 SQLAlchmey를 사용하고 있습니다. 몇 가지 모델/스키마를 만들었고 잘 작동합니다. 이제 기존의 mysql 데이터베이스를 쿼리 할 필요가있다. select 문을 삽입/업데이트하지 않아도된다.sqlalchemy 기존 데이터베이스 쿼리

기존 데이터베이스의 테이블 주위에 래퍼를 만들려면 어떻게해야합니까? 나는 잠시 sqlalchemy 워드 프로세서를 통과했지만 관련성이없는 것은 찾지 못했습니다. 모든 것은 SA 모델과 함께 사용하는 것과 같은 방식으로 SQLAlchmey 쿼리 메소드를 사용하려는 동안 원시 SQL 쿼리를 작성해야하는 메소드를 실행하는 방법을 제안합니다. 기존의 DB는 다음 테이블 이름의 사용자가있는 경우 예를 들어

나는 당신은 SQLAlchemy의 만 작업 할 수 있다는 인상을 갖고있는 것 같다

+0

당신이 사용하는 것 [반사] (http://docs.sqlalchemy.org/en/latest/core/reflection.html를) 매핑 된 클래스로 작업하려면 [automap] (http://docs.sqlalchemy.org/en/latest/orm/extensions/automap.html)을 참조하십시오. –

답변

3

(아마와 결합만을 선택 운영) dbsession를 사용하여 조회 할 SQLAlchemy에 의해 생성 된 데이터베이스 구조 (아마도 MetaData.create_all()을 사용) - 이것이 올바르지 않습니다. SQLAlchemy는 기존 데이터베이스와 완벽하게 작동 할 수 있으므로 데이터베이스 테이블과 일치하도록 모델을 정의하면됩니다. Ilja Everilä에서 알 수 있듯이 그렇게하는 한 가지 방법은, 반사를 사용하는 것입니다

, 내 의견으로는, 일회성 스크립트를 완전히 잘 될 것이라고하지만, "진짜"에 매우 실망 버그로 이어질 수
class MyClass(Base): 
    __table__ = Table('mytable', Base.metadata, 
        autoload=True, autoload_with=some_engine) 

(데이터베이스 구조가 시간이 지남에 따라 변경 될 가능성이있는 경우 응용 프로그램)

또 다른 방법은 모델을 데이터베이스 테이블과 일치하도록 정의하여 평소대로 모델을 정의하는 것입니다. 그리 어렵지 않습니다. 이 접근 방식의 이점은 데이터베이스 테이블의 하위 집합 만 모델에 매핑 할 수 있으며 테이블 열의 하위 집합 만 모델의 필드에 매핑 할 수도 있다는 것입니다. 데이터베이스에서 10 표하지만 당신은 단지 id, name을 필요로하는 곳에 만 관심이 users 테이블과 email 필드가 있다고 가정 :

class User(Base): 
    id = sa.Column(sa.Integer, primary_key=True) 
    name = sa.Column(sa.String) 
    email = sa.Column(sa.String) 

(우리는 단지에 필요한 몇 가지 세부 사항을 정의 할 필요가 없었다 방법주의 문자열 필드의 길이 또는 email 필드에 인덱스가있는 것과 같은 올바른 DDL을 내 보냅니다.

코드에서 모델을 만들거나 수정하지 않으면 SQLAlchemy에서 INSERT/UPDATE 쿼리를 내 보내지 않습니다. 쿼리가 읽기 전용인지 확인하려면 데이터베이스에 특수 사용자를 만들고 해당 사용자에게 SELECT 권한 만 부여 할 수 있습니다. 대안으로/추가적으로, 애플리케이션 코드에서 트랜잭션을 롤백 할 수도 있습니다.

+0

감사합니다. 리플렉션을 사용하여 automap을 사용했지만 제안 사항도 좋습니다. SO 사용자의 경우 시간이되면 Automap의 한 가지 예도 추가 할 수 있습니다. 이 답변을 완료 할 것입니다 – DevC

+0

@ DevC : 감사합니다, 나는 예제를 추가했습니다. – Sergey

0

는 다음과 같은 코드를 사용하여 기존 테이블에 액세스 할 수 있습니다

from sqlalchemy.orm import Session 

Base = automap_base() 
Base.prepare(engine, reflect=True) 
Users = Base.classes.users 
session = Session(engine) 
res = session.query(Users).first()