0

SQLAlchemy を使用して SQLite DB から取得した情報を表示する ObjectListView があります。

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")
])

Loan という 3 つのモデルもあります。

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)

ObjectListView の情報を取得して表示するために、テーブル (loansおよび) を結合しようとしています。peopleこれが私のクエリ方法です:

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テーブルに保存されているすべてのフィールドを取得して表示できますが、ObjectListView では姓名 (peopleテーブルから取得して結合する必要がありますperson.id) が空白です。peopleSQL 出力がオンになっているので、クエリを確認できますが、テーブルからまったく選択されていません。

query/ObjectListView を変更して、この情報を取得して表示するにはどうすればよいですか。?

更新:ここで実行可能なサンプル スクリプトを作成しました。

4

2 に答える 2

1

Loan (qry = session.query(Loan)) のクエリのみを実行しています。SELECT ステートメントにあるもの以外に、結果に別のものが含まれることを期待するのはなぜですか?

于 2012-02-14T18:42:02.450 に答える
0

私自身、SQLAlchemy にはかなり慣れていないことを認めますが、クエリの結果を表示するために使用するものを共有したいと思いました。4 つ以上のテーブルを持つ SQLite DB を使用するプログラムがあり、1 つのクエリで 2 ~ 3 つのテーブルからデータを取得し、この情報を ObjectListView に表示します。Mike Driscoll の詳細なチュートリアル、特にwxPython と 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

ここで重要な部分は次の 2 行です。

record.person.fname
record.person.sname

確立されたリレーションシップを使用して別のテーブルから情報を取得したいので、そのリレーションシップを参照して実際にデータを確認することが重要です。

そして、ObjectListView ウィジェットを設定するには:

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

これがお役に立てば幸いです。

-マイクS

于 2013-11-08T21:58:40.283 に答える