2012-03-17 3 views
1

필자는 수년 동안 일련의 텍스트 파일을 처리하기 위해 사용해온 파이썬 모듈을 사용하고 있습니다. 이제는 db (SQLAlchemy 사용)에 정보를 저장할 필요가 있지만 데이터베이스 지원없이 모듈을 사용할 수있는 유연성이 필요합니다. 즉, 실제로 sqlalchemy를 가져올 필요가 없습니다 (또는 설치됨). 지금 현재로, 나는 다음과 같은 것을 가지고있다 ... 나는 dbher를 사용 할지를 결정하는 wether에 따라 Product 또는 DBProduct 등을 만들고있다.런타임에서 데이터베이스 지원 추가

from sqlalchemy.ext.declarative import declarative_base 

Base = declarative_base() 

class Product(object): 
    pass 

class WebSession(Product): 
    pass 

class Malware(WebSession): 
    pass 

class DBProduct(Product, Base): 
    pass 

class DBWebSession(WebSession, DBProduct): 
    pass 

class DBMalware(Malware, DBWebSession): 
    pass 

그러나 나는 이것을 할 수있는 더 쉽고/깨끗한 방법이 있어야한다고 생각합니다. 나는 상속 혼란과 잠재적 문제들을 길 아래로 만들고 있다고 느낍니다. 이상 적으로는 db를 사용하기 위해 필요한 정보가 들어있는 Product, WebSession 등의 단일 클래스를 만들고 싶습니다.하지만 enable_db_support()과 같은 것을 호출 한 후에 만 ​​활성화/기능 할 수 있습니다. 일단 그 함수가 호출되면, 내가 생성 한 객체와 관계없이 그 자체 (상속받은 모든 객체)는 모든 열 바인딩을 사용 가능하게합니다. 또한 어떻게 든 ProductDBProduct을 하나에 포함시키는 방법을 찾으면 클래스, 때로는 동일한 기능의 2 버전이 필요합니다 : 1은 DB 지원이 가능하면 호출되고 그렇지 않으면 1입니다. 또한 enable_db_support()이 호출 될 때 객체 계층 구조를 "재현"하는 것으로 간주했지만, 악몽으로 밝혀졌습니다.

도움을 주시면 감사하겠습니다.

답변

0

입니다.그들이 SA에 사용되는이 경우, 그러나, 당신은 relationships을 사용할 수 없습니다 만, 간단한 데이터 모델의 가져 오기/내보내기 유형이 충분해야합니다

# models.py 
class User(object): 
    pass 

---- 

# mappings.py 
from sqlalchemy import Table, MetaData, Column, ForeignKey, Integer, String 
from sqlalchemy.orm import mapper 
from models import User 

metadata = MetaData() 

user = Table('user', metadata, 
      Column('id', Integer, primary_key=True), 
      Column('name', String(50)), 
      Column('fullname', String(50)), 
      Column('password', String(12)) 
     ) 

mapper(User, user) 

또 다른 옵션은하는 것 다른 모듈에 정의 된 모델에 대한 기본 클래스가 있고 configure 시작시이 기본 클래스는 DB를 인식하는지 여부를 결정하고 DB 인식 버전의 경우 관계 및 엔진 구성과 같은 추가 기능을 추가하십시오.

+0

감사합니다. 이것은 나를 위해 효과가있을 가능성이 있습니다. 나는 관계 문제를 조사해야 할 것입니다. 나는 '관계'에 많이 의지하는 경향이 있지만 여전히 효과가있을 수 있습니다. 감사. – redlamb

+0

더 생각해 보면이 접근 방식을 고려해 보았지만 데이터베이스에 정보를 저장할 때 클래스의 정의 된 함수 중 일부를 잠재적으로 무시할 필요가 없었기 때문에 이러한 접근 방식을 고려하지 않았다고 생각합니다. 이 접근 방식을 사용하여 클래스의 기능 중 일부를 재정의하는 것이 가능한지 (또는 내가 어떻게 할 것인가) 알고 있습니까? 다시 한번 감사드립니다. – redlamb

+0

@redlamb : 글쎄, 강력한 파이썬의 힘으로 클래스에 메소드를 할당함으로써 관계를 enable_db_support()에 추가 할 수있다 : DBProduct.versions = relationship ('ProductVersion', ...) '. 동일한 방법으로 메소드를 오버라이드 할 수 있습니다 :'def db_override_me (self, param1, ...) : ...'과 같은 새로운 (바인딩되지 않은) 메소드를 정의한 다음 클래스에 다시 할당하십시오 :'DBProduct .override_me = db_override_me'. 나는이 유형의 디자인에 더 나은 해결책이 있을지도 모른다는 두려워하지만 ... – van

0

DRYest 할 일은 데이터 저장 형식의 세부 사항을 추상 텍스트 파일이나 데이터베이스로 추상화하는 것입니다.

즉, 다른 코드가 데이터를 저장하는 데 사용하는 일종의 추상화 계층을 작성하고 추상화 계층의 출력을 SQL 또는 텍스트간에 전환 할 수 있도록합니다.

또 다른 방법으로는 ProductDB_Product 클래스를 쓰지 마십시오. 대신 format='text' 또는 format='db' 중 하나를 사용하도록 지시 할 수있는 store_data() 함수를 작성하십시오. 그런 다음 모든 곳에서 사용하십시오.

이것은 실제로 SQLAlchemy가 백그라운드에서 수행하는 것과 동일합니다. mySQL, PostgreSQL 등을 구동하는지 여부에 따라 SQLAlchemy에 대한 별도의 코드를 작성할 필요가 없습니다. SQLAlchemy에서 모두 처리되며 추상화 된 (데이터베이스 중립적 인) 인터페이스. SQLAlchemy로 이의가 파이썬 내장 아니라고 경우


는 다른 방법으로, 항상 sqlite3있다. 이것은 지방이없는 SQL 관계형 데이터베이스의 장점을 모두 제공합니다.


또는 번갈아 가며, 중간 형식으로 sqlite3을 사용하십시오. 따라서 모두 코드를 sqlite3으로 다시 작성한 다음 필요에 따라 sqlite3에서 일반 텍스트 (또는 다른 데이터베이스)로 변환하십시오. 한계의 경우, 일반 텍스트로 변환하면 아마 declarative 확장을 사용하지 않고 Classical Mapping를 사용하여 순수 비 DB 인식 모델을 만드는 멀리 얻을 수있는, 잘 만 sqlite3 db .dump away.

+0

'store_data()'접근법이 가능 합니다만,'SQLAlchemy'가 제공하는 "이음새없는"것을 잃을 것입니다. 또한, 나는 함수를 호출하고 가능성이 업데이 트를위한 다른 하나를 기억해야 할 것이다. 나는 SQLAlchemy를 사용하는 데 반대 의견이 없으며, 사실, 데이터를 영구적으로 만들 때 사용하고있다. 데이터베이스. 그러나 I (또는 동료)가 데이터를 데이터베이스에 저장할 필요가없는 많은 경우가 있습니다. 이러한 상황에서 필자는 SQLAlchemy (또는 db 드라이버)가 필수 설치/가져 오기가 아닌 것을 선호합니다. 응답에 대해 – redlamb

관련 문제