首页 > 解决方案 > 是否可以在 SQLAlchemy 中创建自定义“列”?这是破坏 OOP 吗?

问题描述

我是 SQLAlchemy 的新手,我正在尝试理解一些概念。

这是一个没有 SQLAlchemy 的代码示例:

class Token:
    def __init__(self, key):
        # generate token based on a string

class User:
    def __init__(self, name):
        self.name = name
        self.token = Token(name)

    def check_token(token_to_check)
        return self.token.is_valid(token_to_check)

如何将其移至 SQLAlchemy?我想我必须做类似的事情:

class UserDatabase(Base):
    __tablename__ = 'testing_sql_alchemy_v2_users'
    name = Column(String(256))
    token = Column(String(256))

但是,当我得到用户时,令牌将是一个字符串而不是一个令牌对象。我可以用我的对象创建一个列吗?例子:

token = Column(Token)

如果我不能这样做,我所有使用数据库的对象都必须只有“简单”变量(字符串、int 等)。我认为这会破坏 OOP,对吧?

标签: pythonsqloopsqlalchemy

解决方案


在模型 ( class UserDatabase) 中定义列时,您仅限于您正在使用的数据库引擎中存在的类型。

但是,一些数据库引擎允许您克服这个困难。

在 PostgreSQL 中,可以通过纯 SQL 或使用 ORM(如 SQLAlchemy)定义您自己的自定义类型。

import sqlalchemy.types as types

class MyType(types.TypeDecorator):
    '''Prefixes Unicode values with "PREFIX:" on the way in and
    strips it off on the way out.
    '''

    impl = types.Unicode

    def process_bind_param(self, value, dialect):
        return "PREFIX:" + value

    def process_result_value(self, value, dialect):
        return value[7:]

    def copy(self, **kw):
        return MyType(self.impl.length)

来源:SQLAlchemy Docs

正如您所看到的,它在现有类型之上实现了额外的逻辑,因此它是有限的。

但是对于您的用例,它应该就足够了 - 您可以在类型之上创建自己的varchar类型并执行一些逻辑来标记该字符串。


推荐阅读