2013-09-06 13 views
7

Sto cominciando a incorporare Alambicco nel mio progetto, che utilizza già le definizioni SQLAlchemy tavolo. Al momento il mio schema DB è gestito esternamente alla mia applicazione e voglio portare l'intero schema nel mio file di definizioni di tabelle.Come rappresentare un dominio PostgreSQL personalizzato in SQLAlchemy?

In PostgreSQL Io uso un dominio personalizzato per la memorizzazione di indirizzi di posta elettronica. Il PostgreSQL DDL è:

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

Come si rappresentano la creazione di questo dominio, e l'uso di esso come un tipo di dati di colonna, in SQLAlchemy?

+1

Questa domanda sembra un po 'più avanzato, forse si può trovare di meglio di aiuto alla lista SQLAlchemy. Per l'utilizzo del tipo, consiglierei di trovare un modo per creare sottoclassi 'TEXT' e cambiarne il nome in' email_address'. Questo sarebbe il modo più semplice (ma non so come farlo). L'ultima parte potrebbe probabilmente essere eseguita da SQL letterale, perché non sono sicuro che SQLAlchemy abbia un'interfaccia per la creazione di tipi che non esistono ancora. – javex

+0

@javex per ora sto creando il dominio mediante l'emissione di DDL costume e ho sottoclasse 'UserDefinedType' per tornare' email_address' per la sua definizione tipo di colonna. Non ideale ma funziona abbastanza bene. Potrei controllare l'elenco SQLA, grazie per questo suggerimento. – skyler

risposta

0

Questo probabilmente lontano da una soluzione di lavoro, ma penso che il modo migliore per farlo sarebbe sottoclasse 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 

Ovviamente, questa è incompleta, ma dovrebbe dare un buon punto di partenza se si desidera che questo abbastanza male. :)

Problemi correlati