2013-09-06 12 views
7

Zaczynam wprowadzać Alembic do mojego projektu, który już używa definicji tabel SQLAlchemy. Obecnie mój schemat bazy danych jest zarządzany na zewnątrz mojej aplikacji i chcę wprowadzić cały schemat do pliku definicji tabel.Jak reprezentować niestandardową domenę PostgreSQL w SQLAlchemy?

W PostgreSQL używam domeny niestandardowej do przechowywania adresów e-mail. PostgreSQL DDL jest:

CREATE DOMAIN email_address TEXT CHECK (value ~ '[email protected]+') 

Jak mogę reprezentować tworzenia tej domenie i użycie go jako typ danych kolumny w SQLAlchemy?

+1

To pytanie wydaje się nieco bardziej zaawansowane, może znajdziesz lepszą pomoc na liście SQLAlchemy. Do korzystania z tego typu polecam znalezienie sposobu na podklasę "TEKSTU" i zmianę jej nazwy na "adres_adresowy". To byłby najprostszy sposób (ale nie wiem jak to zrobić). Ostatnia część mogłaby prawdopodobnie zostać wykonana przez dosłowny SQL, ponieważ nie jestem pewien, czy SQLAlchemy ma interfejs do tworzenia typów, które jeszcze nie istnieją. – javex

+0

@javex na razie tworzę domenę, wydając niestandardowy DDL i podklasowałem 'UserDefinedType', aby zwrócić' email_address' dla definicji typu kolumny. Nie idealne, ale działa wystarczająco dobrze. Mogę sprawdzić listę SQLA, dziękuję za tę sugestię. – skyler

Odpowiedz

0

Prawdopodobnie daleki od sprawnego rozwiązania, ale myślę, że najlepszym sposobem na zrobienie tego byłaby podklasa sqlalchemy.schema._CreateDropBase.

from sqlalchemy.schema import _CreateDropBase 

class CreateDomain(_CreateDropBase): 
    '''Represent a CREATE DOMAIN statement.''' 

    __visit_name__ = 'create_domain' 

    def __init__(self, element, bind=None, **kw): 
     super(CreateDomain, self).__init__(element, bind=bind, **kw) 

class DropDomain(_CreateDropBase): 
    '''Represent a DROP BASE statement.''' 

    __visit_name__ = 'drop_domain' 

    def __init__(self, element, bind=None, **kw): 
     super(DropDomain, self).__init__(element, bind=bind, **kw) 

@compiles(CreateDomain, 'postgresql') 
def visit_create_domain(element, compiler, **kw): 
    text = '\nCREATE DOMAIN %s AS %s' % (
     compiler.prepare.format_column(element.name), 
     compiler.preparer.format_column(element.type_)) # doesn't account for arrays and such I don't think 

    default = compiler.get_column_default_string(column) 
    if default is not None: 
     text += " DEFAULT %s" % default 

    return text 

Oczywiście, jest to niekompletne, ale powinno dać dobry punkt wyjścia, jeśli chcesz tego wystarczająco mocno. :)

Powiązane problemy