与 SQLAlchemy 中列的切片和铸造值的关系
relationship with a sliced and casted value of the column in SQLAlchemy
有什么方法可以分别基于 parent_id
和 id
在 Parent 和 Child 之间创建这样的关系(示例数据):
Parent
parent_id: "A1234"
姓名:"Parent Name"
Child
编号:1234
如何将外键添加到 Child
? parent_id
是 String
。有没有办法将它切片然后转换为 Integer
?
编辑:
另外,如果情况相反怎么办:
Child:
child_id: "A1234"
Parent:
parent_letter: "A"
parent_id: 1234
会不会像这样:
primaryjoin=(child_id == (Parent.parent_letter + str(Parent.parent_id)))
remote_side
会是什么样子?还是整个 relationship
?
请参阅文档的 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.children
或 Child.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
Edit-1:对于您在评论和编辑中提到的另一种情况,以下关系定义应该有效(显然,模型的定义也不同):
parent = relationship(
Parent,
primaryjoin=(
foreign(child_id) ==
remote(Parent.parent_letter + cast(Parent.parent_id, String))
),
backref="children",
uselist=False,
)
有什么方法可以分别基于 parent_id
和 id
在 Parent 和 Child 之间创建这样的关系(示例数据):
Parent
parent_id: "A1234"
姓名:"Parent Name"
Child
编号:1234
如何将外键添加到 Child
? parent_id
是 String
。有没有办法将它切片然后转换为 Integer
?
编辑: 另外,如果情况相反怎么办:
Child:
child_id: "A1234"
Parent:
parent_letter: "A"
parent_id: 1234
会不会像这样:
primaryjoin=(child_id == (Parent.parent_letter + str(Parent.parent_id)))
remote_side
会是什么样子?还是整个 relationship
?
请参阅文档的 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.children
或 Child.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
Edit-1:对于您在评论和编辑中提到的另一种情况,以下关系定义应该有效(显然,模型的定义也不同):
parent = relationship(
Parent,
primaryjoin=(
foreign(child_id) ==
remote(Parent.parent_letter + cast(Parent.parent_id, String))
),
backref="children",
uselist=False,
)