2013-09-06 35 views
7

Tôi đang bắt đầu kết hợp Alembic vào dự án của tôi đã sử dụng định nghĩa bảng SQLAlchemy. Hiện tại lược đồ DB của tôi được quản lý bên ngoài ứng dụng của tôi và tôi muốn đưa toàn bộ lược đồ vào tệp định nghĩa bảng của tôi.Cách thể hiện một miền PostgreSQL tùy chỉnh trong SQLAlchemy?

Trong PostgreSQL tôi sử dụng tên miền tùy chỉnh để lưu trữ địa chỉ email. Các PostgreSQL DDL là:

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

Làm thế nào để đại diện cho việc tạo ra các lĩnh vực này, và việc sử dụng nó như là một kiểu dữ liệu cột, trong SQLAlchemy?

+1

Câu hỏi này có vẻ cao cấp hơn một chút, có thể bạn sẽ tìm thấy trợ giúp tốt hơn trong danh sách SQLAlchemy. Đối với việc sử dụng loại tôi muốn khuyên bạn nên tìm một cách để phân lớp 'TEXT' và thay đổi tên của nó thành' email_address'. Đây sẽ là cách đơn giản nhất (nhưng tôi không biết phải làm thế nào). Phần sau có lẽ có thể được thực hiện bởi SQL theo nghĩa đen, bởi vì tôi không chắc SQLAlchemy có một giao diện để tạo các kiểu chưa tồn tại. – javex

+0

@javex bây giờ tôi đang tạo tên miền bằng cách phát hành DDL tùy chỉnh và tôi đã phân lớp 'UserDefinedType' để trả về' email_address' cho định nghĩa kiểu cột của nó. Không lý tưởng nhưng nó hoạt động đủ tốt. Tôi có thể kiểm tra danh sách SQLA, cảm ơn bạn đã gợi ý này. – skyler

Trả lời

0

Điều này có thể xa giải pháp làm việc, nhưng tôi nghĩ cách tốt nhất để làm điều này sẽ là phân lớp 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 

Rõ ràng, điều này chưa hoàn chỉnh, nhưng nó sẽ cung cấp cho bạn một điểm khởi đầu tốt nếu bạn muốn điều này đủ tồi tệ. :)

Các vấn đề liên quan