在SQLAlchemy中查询连接表并在ObjectListView中显示

时间:2012-02-13 15:58:26

标签: python join wxpython sqlalchemy objectlistview

我有一个ObjectListView,它显示从带有SQLAlchemy的SQLite DB中检索的信息。

def setupOLV(self):
    self.loanResultsOlv.SetEmptyListMsg("No Loan Records Found")
    self.loanResultsOlv.SetColumns([
    ColumnDefn("Date Issued", "left", 100, "date_issued",
                stringConverter="%d-%m-%y"),
    ColumnDefn("Card Number", "left", 100, "card_id"),
    ColumnDefn("Student Number", "left", 100, "person_id"),
    ColumnDefn("Forename", "left", 150, "person_fname"),
    ColumnDefn("Surname", "left", 150, "person_sname"),
    ColumnDefn("Reason", "left", 150, "issue_reason"),
    ColumnDefn("Date Due", "left", 100, "date_due", 
                stringConverter="%d-%m-%y"),
    ColumnDefn("Date Returned", "left", 100, "date_returned", 
                stringConverter="%d-%m-%y")
])

我还有三个模型,贷款:<​​/ p>

class Loan(DeclarativeBase):
    """
    Loan model
    """
    __tablename__ = "loans"

    id = Column(Integer, primary_key=True)
    card_id = Column(Unicode, ForeignKey("cards.id"))
    person_id = Column(Unicode, ForeignKey("people.id"))
    date_issued = Column(Date)
    date_due = Column(Date)
    date_returned = Column(Date)
    issue_reason = Column(Unicode(50))
    person = relation("Person", backref="loans", cascade_backrefs=False)
    card = relation("Card", backref="loans", cascade_backrefs=False)

人:

class Person(DeclarativeBase):
    """
    Person model
    """
    __tablename__ = "people"

    id = Column(Unicode(50), primary_key=True)
    fname = Column(Unicode(50))
    sname = Column(Unicode(50))

和卡:

class Card(DeclarativeBase):
    """
    Card model
    """
    __tablename__ = "cards"

    id = Column(Unicode(50), primary_key=True)
    active = Column(Boolean)

我正在尝试加入表(loanspeople)以检索和显示ObjectListView中的信息。这是我的查询方法:

def getQueriedRecords(session, filterChoice, keyword):
    """
    Searches the database based on the filter chosen and the keyword
    given by the user
    """
    qry = session.query(Loan)
    if filterChoice == "person":
        result = qry.join(Person).filter(Loan.person_id=='%s' % keyword).all()
    elif filterChoice == "card":
        result = qry.join(Person).filter(Loan.card_id=='%s' % keyword).all()
    return result

我可以检索并显示存储在loans表中的每个字段,但是forename和surname(应该从people表中绘制并加入person.id)在我的ObjectListView中是空白的。我有SQL输出,所以我可以看到查询,它根本没有从people表中选择。

如何修改查询/ ObjectListView以检索和显示此信息。吗

更新:我创建了一个可运行here的示例脚本。

2 个答案:

答案 0 :(得分:1)

您只需要查询贷款(qry = session.query(贷款))。除了SELECT语句中的内容之外,为什么还要在结果中包含其他内容?

答案 1 :(得分:0)

我承认我自己对SQLAlchemy很新,但我想我会分享用于显示查询结果的内容。我有一个程序使用带有4个以上表的SQLite数据库,我在一个查询中从2-3个数据中提取数据,并在ObjectListView中显示此信息。我欠Mike Driscoll的深度教程,特别是wxPython and SqlAlchemy: An Intro to MVC and CRUD

以下是我可能在代码中添加/更改的内容。

在模型部分添加“显示”类,例如:

def OlvDisplay(object):
    def __init__(self, date_issued, card_id, person_id, fname, sname,
                 issue_reason, date_due, date_returned):
        self.date_issued   = date_issued
        self.card_id       = card_id
        self.person_id     = person_id
        self.person_fname  = fname
        self.person_sname  = sname
        self.issue_reason  = issue_reason
        self.date_due      = date_due
        self.date_returned = date_returned

此显示类用于下面的convertResults定义,并帮助确保为ObjectListView正确格式化数据。

对现有查询功能的调整:

def getQueriedRecords(session, filterChoice, keyword):
    """
    Searches the database based on the filter chosen and the keyword
    given by the user
    """
    qry = session.query(Loan)
    if filterChoice == "person":
        result = qry.join(Person).filter(Loan.person_id=='%s' % keyword).all()
    elif filterChoice == "card":
        result = qry.join(Person).filter(Loan.card_id=='%s' % keyword).all()
    convertedResults = convertResults(result)
    return convertedResults

我们在这里做的是创建一个本地变量,该变量基本上运行转换定义并存储下一行的结果,然后返回这些结果。

和“转换器”功能:

def convertResults(results):
    finalResults = []
    for record in results:
        result = OlvDisplay(
                        record.date_issued,
                        record.card_id,
                        record.person_id,
                        record.person.fname,
                        record.person.sname,
                        record.issue_reason,
                        record.date_due,
                        record.date_returned
                           )
        finalResults.append(result)
    return finalResults

这里重要的部分是两行:

record.person.fname
record.person.sname

由于我们希望使用已建立的关系从另一个表中提取信息,因此引用该关系来实际查看数据非常重要。

填充ObjectListView小部件:

theOutput = getQueriedRecords(session, filterChoice, keyword)
self.setupOLV.SetObjects(theOutput)

希望这可以帮助你。

-MikeS