与SQLAlchemy中列的切片和转换值的关系

时间:2015-05-05 15:40:19

标签: python sqlalchemy

有没有办法分别根据parent_idid在Parent和Child之间创建这样的关系(示例数据):


parent_id:“A1234”
名称:“父名”

儿童
id:1234

如何将外键添加到Childparent_idString。有没有办法将其切片然后转换为Integer

修改 如果情况发生在其他方面也是如此:

儿童:
child_id:“A1234”

父:
parent_letter:“A”
parent_id:1234

会是这样的:
primaryjoin=(child_id == (Parent.parent_letter + str(Parent.parent_id)))

remote_side会是什么样子?还是整个relationship

1 个答案:

答案 0 :(得分:2)

请参阅文档的Creating Custom Foreign Conditions部分。使用cast,可以为以下模型设置关系:

class Parent(Base):
    __tablename__ = 'parent'
    parent_id = Column(String, primary_key=True)
    name = Column(String, nullable=False)


class Child(Base):
    __tablename__ = 'child'
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)

    parent = relationship(
        Parent,
        primaryjoin=("A" + cast(id, String) == Parent.parent_id),
        foreign_keys=id,
        remote_side=Parent.parent_id,
        backref="children",
        # uselist=False,  # use in case of one-to-one relationship
    )

在这种情况下,您可以查询 Parent.childrenChild.parent

p1 = session.query(Parent).get('A1234')
print(p1)
print(p1.children)

c1 = session.query(Child).get(1234)
print(c1)
print(c1.parent)

但是,您仍然无法创建关系项,如下所示:

p = Parent(
    parent_id='A3333', name='with a child',
    children=[Child(name='will not work')]
)
session.add(p)
session.commit()  # this will fail

编辑-1 :对于您在评论和编辑中提到的替代案例,以下关系定义应该有效(显然,模型的定义也不同):

parent = relationship(
    Parent,
    primaryjoin=(
        foreign(child_id) ==
        remote(Parent.parent_letter + cast(Parent.parent_id, String))
    ),
    backref="children",
    uselist=False,
)