【问题标题】:SQLAlchemy - MappedCollection problemSQLAlchemy - MappedCollection 问题
【发布时间】:2010-10-22 02:03:53
【问题描述】:

我在 Python 的 SQLAlchemy 中设置字典集合时遇到了一些问题:

我正在使用表的声明性定义。我有Item 表与Record 表的1:N 关系。我使用以下代码设置了关系:

_Base = declarative_base()

class Record(_Base):
    __tablename__ = 'records'

    item_id = Column(String(M_ITEM_ID), ForeignKey('items.id'))
    id = Column(String(M_RECORD_ID), primary_key=True)
    uri = Column(String(M_RECORD_URI))
    name = Column(String(M_RECORD_NAME))

class Item(_Base):
    __tablename__ = 'items'

    id = Column(String(M_ITEM_ID), primary_key=True)

    records = relation(Record, collection_class=column_mapped_collection(Record.name), backref='item')

现在我想使用Items 和Records。让我们创建一些对象:

i1 = Item(id='id1')
r = Record(id='mujrecord')

现在我想使用以下代码关联这些对象:

i1.records['source_wav'] = r

但是Record r 没有设置name 属性(外键)。有什么解决方案如何自动确保这一点? (我知道在Record 创建过程中设置外键是可行的,但这对我来说并不好)。

非常感谢

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    你想要这样的东西:

    from sqlalchemy.orm import validates
    
    class Item(_Base):
        [...]
    
        @validates('records')
        def validate_record(self, key, record):
          assert record.name is not None, "Record fails validation, must have a name"
          return record
    

    这样,您就可以得到所需的验证:

    >>> i1 = Item(id='id1')
    >>> r = Record(id='mujrecord')
    >>> i1.records['source_wav'] = r
    Traceback (most recent call last):
      [...]
    AssertionError: Record fails validation, must have a name
    >>> r.name = 'foo'
    >>> i1.records['source_wav'] = r
    >>> 
    

    【讨论】:

      【解决方案2】:

      我还不能发表评论,所以我将把它写成一个单独的答案:

      从 sqlalchemy.orm 导入验证
      
      类项目(_Base):
          [...]
      
          @validates('记录')
          def validate_record(self, key, record):
            记录名称=键
            退货记录
      

      这基本上是 Gunnlaugur 答案的副本,但滥用 validates 装饰器来做一些比爆炸更有用的事情。

      【讨论】:

        【解决方案3】:

        你有:

        backref='item'
        

        这是一个错字

        backref='name'
        

        ?

        【讨论】:

        • 可能不会。 backref 是 sqlalchemy 将添加到关系的另一端(Record 类)的属性的名称,以引用包含前向引用的对象(Item 实例)。所以“item”是有道理的——在 honzas 的例子中,r.item 产生了 Item 实例。
        猜你喜欢
        • 2022-10-07
        • 2022-11-17
        • 2010-11-01
        • 2010-10-09
        • 2011-01-13
        • 2010-12-03
        • 2011-09-23
        • 1970-01-01
        • 2010-11-03
        相关资源
        最近更新 更多