SQLalchemy以声明方式描述关联对象的正确方法是什么

时间:2010-02-28 17:47:53

标签: python sqlalchemy

我正在寻找一种以声明方式描述关联对象的方法。除了将外键存储在关联表中之外,我还需要存储关联的创建日期等信息。

今天,我的模型看起来像这样:

# Define the User class
class User(Base):
    __tablename__ = 'users'

    # Define User fields
    id = schema.Column(types.Integer(unsigned=True),
        schema.Sequence('users_seq_id', optional=True), primary_key=True)
    password = schema.Column(types.Unicode(64), nullable=False)

# Define the UserSubset class
class UserSubset(Base):
    __tablename__ = 'subsets'

    # Define UserSubset fields
    id = schema.Column(types.Integer(unsigned=True),
        schema.Sequence('subsets_seq_id', optional=True), primary_key=True)
    some_short_description = schema.Column(types.Unicode(50), nullable=False)

# Define the subset memberships table
subset_memberships = schema.Table('group_memberships', Base.metadata,
    schema.Column('user_id', types.Integer(unsigned=True), ForeignKey('users.id')),
    schema.Column('subset_id', types.Integer(unsigned=True), ForeignKey('subsets.id')),
    schema.Column('created', types.DateTime(), default=now, nullable=False),
)

我可以连接关联对象中的所有内容吗?或者我应该使用声明方式更改停止?

2 个答案:

答案 0 :(得分:1)

您目前使用的只是一个多对多关系。 docs

中介绍了如何使用关联对象

还有一个名为associationproxy的扩展名,它简化了关系。

答案 1 :(得分:0)

正如您在the manual中所看到的,配置一对多关系非常简单:

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    addresses = relation("Address", backref="user")

class Address(Base):
    __tablename__ = 'addresses'

    id = Column(Integer, primary_key=True)
    email = Column(String(50))
    user_id = Column(Integer, ForeignKey('users.id'))

Many to many relations并不难:

  

声明性的多对多并没有什么特别之处。 relation()的辅助参数仍然需要Table对象,而不是声明性类。表应该共享声明性基础使用的相同MetaData对象:

 keywords = Table('keywords', Base.metadata,
                     Column('author_id', Integer, ForeignKey('authors.id')),
                     Column('keyword_id', Integer, ForeignKey('keywords.id'))
             )

 class Author(Base):
     __tablename__ = 'authors'
     id = Column(Integer, primary_key=True)
     keywords = relation("Keyword", secondary=keywords)
     

您通常应该映射一个类,并以多对多关系指定其表,因为ORM可能会发出重复的INSERT和DELETE语句。

无论如何,inheritance可能会更好地为您提供服务。当然,可能存在复杂的表关系,这将是声明性方式的病态情况,但这似乎不是其中之一。

还有一件事,代码注释应说明以下代码的作用是什么,而不是它是如何做的。发表# Define the User class评论几乎就像有一行代码a = 1 # assing value 1 to variable "a"