2010-07-21 3 views
4

SqlAlchemy (0.5.8)를 사용하여 선언적으로 레거시 데이터베이스와 상호 작용하고 리플렉션을 사용하려고합니다. 내 테스트 코드는 다음과 같습니다SqlAlchemy에서 db를 반사 할 때 외래 키 관계가 누락 됨

from sqlalchemy import * 
from sqlalchemy.orm import create_session 
from sqlalchemy.ext.declarative import declarative_base 

Base = declarative_base() 
engine = create_engine('oracle://schemaname:[email protected]') 
meta = MetaData(bind=engine) 

class CONSTRUCT(Base): 
    __table__ = Table('CONSTRUCT', meta, autoload=True) 

class EXPRESSION(Base): 
    __table__ = Table('EXPRESSION', meta, autoload=True) 

session = create_session(bind=engine) 

을 지금이 (가) (기본 오라클 스키마에 외래 키 제약 조건에 의해 정의)이 두 테이블 사이의 조인을 사용하여 쿼리를 실행하려고 할 때 :

print session.query(EXPRESSION).join(PURIFICATION) 

... 기쁨 없습니다 : 그러나

sqlalchemy.exc.ArgumentError: Can't find any foreign key relationships between 'EXPRESSION' and 'PURIFICATION' 

:

>>> EXPRESSION.epiconstruct_pkey.property.columns 
[Column(u'epiconstruct_pkey', OracleNumeric(precision=10, scale=2, asdecimal=True, 
length=None), ForeignKey(u'construct.pkey'), table=<EXPRESSION>, nullable=False)] 

>>> CONSTRUCT.pkey.property.columns 
[Column(u'pkey', OracleNumeric(precision=38, scale=0, asdecimal=True, length=None), 
table=<CONSTRUCT>, primary_key=True, nullable=False)] 

반사가 외래 키를 선택했음을 분명하게 나타내는 문구.

어디로 잘못 가고 있습니까?

답변

5

Eclipse에서 스크립트 + SqlAlchemy 코드를 디버깅 한 후에 테이블/열 목록이 내부적으로 소문자로 유지된다는 것을 알게되었습니다. 따라서 EXPRESSION.foreignkey와 expression.foreignkey가 일치 할 가능성은 전혀 없습니다. 따라서 오류 메시지.

"오라클, 데이터 사전 대문자 텍스트를 사용하여 모든 대소 문자를 구분 식별자 이름을 나타냅니다 SQLAlchemy의 다른 손으로,이 모두 낮은 고려하십시오 SqlAlchem ​​y의 문서 (http://www.sqlalchemy.org/docs/reference/dialects/oracle.html#identifier-casing)에 깊이 파고

나는 다음은 다음 발견했다. 대소 문자를 구분하지 않는 대소 문자 구분자 이름 Oracle Dialect는 테이블과 색인의 반영과 같이 스키마 레벨 통신 중에 대소 문자를 구분하지 않는 모든 식별자를이 두 형식으로 변환합니다 SQLAlchemy 측에서 UPPERCASE 이름을 사용하면 대소 문자를 구분하는 식별자가 나타납니다. SQLAlchemy가 이름을 인용합니다. 오라클에서 수신 한 데이터 사전 데이터와의 불일치가 발생합니다. 식별자 이름이 실제로 대소 문자를 구분하지 않는 한 (예 : usi 따옴표로 묶인 이름), 모든 소문자 이름은 SQLAlchemy 측에서 사용해야합니다. "

from sqlalchemy import * 
from sqlalchemy.orm import create_session 
from sqlalchemy.ext.declarative import declarative_base 

Base = declarative_base() 
engine = create_engine('oracle://EPIGENETICS:[email protected]') 
meta = MetaData(bind=engine) 

class construct(Base): 
    __table__ = Table('construct', meta, autoload=True) 

class expression(Base): 
    __table__ = Table('expression', meta, autoload=True) 

class purification(Base): 
    __table__ = Table('purification', meta, autoload=True) 

session = create_session(bind=engine) 
print session.query(expression).join(purification,expression) 

... 뱉어 : 그것은 다음과 같습니다 경우

그래서 내 코드가 작동 (차이가 대소 문자 만 변경가)

SELECT expression.pkey AS expression_pkey, expression.cellline AS expression_cellline, expression.epiconstruct_pkey AS expression_epiconstruct_pkey, expression.elnexp AS expression_elnexp, expression.expression_id AS expression_expression_id, expression.expressioncomments AS expression_expressioncomments, expression.cellmass AS expression_cellmass, expression.datestamp AS expression_datestamp, expression.person AS expression_person, expression.soluble AS expression_soluble, expression.semet AS expression_semet, expression.scale AS expression_scale, expression.purtest AS expression_purtest, expression.nmrlabelled AS expression_nmrlabelled, expression.yield AS expression_yield 
FROM expression JOIN purification ON expression.pkey = purification.epiexpression_pkey JOIN expression ON expression.pkey = purification.epiexpression_pkey 

케이스 마감했다.