动态SQLAlchemy类中的列

0 投票
2 回答
918 浏览
提问于 2025-04-18 03:07

我有一些 sqlalchemy 的类,比如:

class OneThing(Base):
    id = Column(Integer, Sequence('one_thing_seq'), primary_key=True)
    thing = Column(Boolean())
    tag = Column(String(255))


class TwoThing(Base):
    id = Column(Integer, Sequence('two_thing_seq'), primary_key=True)
    thing = Column(Boolean())
    tag = Column(String(100))

也就是说,这些类的构造方式是比较标准的。

问题是:有没有办法更灵活地控制列的创建,还是说这必须保持相对固定?我至少想把一些比较普通的列和它们的导入整合到多个文件中,比如这样(不是用 mixin,因为我已经为某些在模型中相同的列使用了 mixin,而是想要一个函数,根据可能的变量返回一个列):

class OneThing(Base):
    id = Base.id_column()
    thing = Base.bool_column
    tag = Base.string_col(255)


class OneThing(Base):
    id = Base.id_column()
    thing = Base.bool_column
    tag = Base.string_col(255)

看起来这个想法挺简单的,我会开始阅读和尝试,但我还没有找到任何例子或者合适的搜索词来查找例子。类的列不一定要是固定的,这可能很简单。这种做法存在吗,还是说这是个愚蠢的想法?

2 个回答

1

Column()这个调用并不是有什么神奇之处;你可以用任何随机的方法来创建合适的对象。真正的“魔法”(也就是把列和变量名、表绑定在一起)发生在Base的元类里。

所以一个解决方案就是你自己写代码,返回一个Column()或者三个——没有什么能阻止你这样做:

class Thing(Base):
    id,thing,tag = my_magic_creator()

另一方面,你可以完全放弃这些赋值操作,把工作放在一个元类里;你可以查看我在这里的回答:在SQLAlchemy中创建自引用表和多态,里面有一个模板教你怎么做。

1
from sqlalchemy import Column, Boolean, Integer

def c_id():
    return Column(Integer, primary_key=True)

def c_bool():
    return Column(Boolean, nullable=False, default=False)

def c_string(len):
    return Column(String(len), nullable=False, default='')

class Thing(Base):
    id = c_id()
    thing = c_bool()
    tag = c_string(255)

SQLAlchemy的开发者在这里讲得更详细:http://techspot.zzzeek.org/2011/05/17/magic-a-new-orm/

撰写回答