2013-09-06 17 views
7

Ich fange an, Alembic in mein Projekt zu integrieren, das bereits SQLAlchemy Tabellendefinitionen verwendet. Derzeit wird mein DB-Schema außerhalb meiner Anwendung verwaltet, und ich möchte das gesamte Schema in meine Tabellendefinitionsdatei bringen.Wie kann ich eine benutzerdefinierte PostgreSQL-Domäne in SQLAlchemy darstellen?

In PostgreSQL verwende ich eine benutzerdefinierte Domain zum Speichern von E-Mail-Adressen. Die PostgreSQL DDL ist:

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

Wie vertrete ich die Schaffung dieser Domäne und die Verwendung davon als Spaltendatentyp, in SQLAlchemy?

+1

Diese Frage scheint ein wenig fortgeschrittener, vielleicht finden Sie bessere Hilfe auf der SQLAlchemy-Liste. Für die Verwendung des Typs würde ich empfehlen, einen Weg zu finden, die 'TEXT' abzuleiten und ihren Namen in' email_address' zu ändern. Dies wäre der einfachste Weg (aber ich weiß nicht, wie es geht). Der letzte Teil könnte wahrscheinlich durch literales SQL erfolgen, da ich nicht sicher bin, ob SQLAlchemy eine Schnittstelle zum Erstellen von Typen hat, die noch nicht existieren. – javex

+0

@javex für jetzt Ich erstelle die Domäne durch Ausgabe von benutzerdefinierten DDL und ich habe 'UserDefinedType' subclasse, um 'email_address' für seine Spaltentypdefinition zurückzugeben. Nicht ideal, aber es funktioniert gut genug. Ich kann die SQLA-Liste überprüfen, danke für diesen Vorschlag. – skyler

Antwort

0

Dies ist wahrscheinlich weit von einer funktionierenden Lösung, aber ich denke, der beste Weg, dies zu tun wäre Subklasse 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 

Offensichtlich ist dies unvollständig, aber es sollte Ihnen einen guten Ausgangspunkt geben, wenn Sie dies stark genug wollen. :)

Verwandte Themen