我有一张表格Fatal error: Uncaught Error: Class 'Google_Client' not found in
/Users/xxxx/app.php:8
Stack trace:
#0 {main}
thrown in /Users/xxxx/app.php on line 8
,它代表在我的应用程序的下拉列表中找到的所有选项。每个选项都可以通过其所属菜单(例如MenuOptions
)和该选项的特定值(MenuOptions.menu_name
)来识别。
此表在我的数据库中具有所有关系,并且不使用外键,因此我很难使其与SQLAlchemy啮合。
在SQL中,它很简单:
MenuOptions.option_value
定义此关系。但是,在SQLAlchemy中这样做时会遇到麻烦,因为如果没有外键,我将无法清晰地映射这种关系。在SQLAlchemy中,到目前为止我做得最好的是:
SELECT
*
FROM
document
JOIN
menu_options ON menu_options.option_menu_name = 'document_type'
AND menu_options.option_value = document.document_type_id
这确实起作用,并且确实返回正确的值,但是将它们作为两个单独的模型对象的列表返回,因此我必须通过the_doc = db.session.query(Document, MenuOptions).filter(
Document.id == document_id
).join(
MenuOptions,
and_(
MenuOptions.menu_name == text('"document_type"'),
MenuOptions.value == Document.type_id
)
).first()
引用映射的Document属性,并通过{{1 }}
有没有一种方法可以让我获得不带外键或模型中任何the_doc[0]
的所有属性作为单个查询对象的返回关系?我已经尝试过the_doc[1]
和ForeignKeyConstraint
,但得到的结果基本相同。
答案 0 :(得分:1)
您可以使用with_entities
entities = [getattr(Document, c) for c in Document.__table__.columns.keys()] + \
[getattr(MenuOptions, c) for c in MenuOptions.__table__.columns.keys()]
session.query(Document, MenuOptions).filter(
Document.id == document_id
).join(
MenuOptions,
and_(
MenuOptions.menu_name == text('"document_type"'),
MenuOptions.value == Document.type_id
)
).with_entities(*entities)
答案 1 :(得分:0)
我最终使用association_proxy
采取了一种略有不同的方法,但是如果您最终从google那里来到这里,那么这应该会对您有所帮助。在以下示例中,我将document_type_id
存储在document
表中,并将该ID的对应值保存在名为menu_options
的表中。通常,您会为此使用外键,但是我们的menu_options
本质上是一个内部查找表,它包含与其他几张表的关系,因此外键不是一个干净的解决方案。
首先通过primaryjoin
属性建立关系,然后使用associationproxy
,我可以使用以下代码立即基于document_type
加载document_type_id
:>
from sqlalchemy import and_
from sqlalchemy.ext.associationproxy import association_proxy
class Document(db.Model):
__tablename__ = "document"
document_type_id = db.Column(db.Integer)
document_type_proxy = db.relationship(
"MenuOptions",
primaryjoin=(
and_(
MenuOptions.menu_name=='document_type',
foreign('Document.document_type_id')==MenuOptions.value
)
),
lazy="immediate"
viewonly=True
)
如果只需要一个映射关系,而无需在数据库中使用外键,那么就可以了。但是,如果您希望能够直接将远程属性(在这种情况下为document_type
)作为初始类(在这种情况下为Document
)上的属性来访问,则可以使用{{1 }}为此,只需传递映射关系的名称和远程属性的名称:
association_proxy