1

これは簡単なことのように思えましたが、方法がわかりません。

私のプロジェクトには、金融取引を保存するトランザクション ログ テーブルがあります。ほとんどの場合、これらのトランザクションを連続して記述する必要があり、それらはすべて多くのプロパティを共有しています。

したがって、私がやりたいことは、1 つの Transactionlog オブジェクトをインスタンス化し、共通のプロパティを入力してから、この元のオブジェクトのコピーをセッションに追加し続けることです。

私の現在のコードは次のようなものです(簡略化され、より大きなクラスメソッドの一部です):

    t = Transactionlog()
    t.tlog_newData = origin
    t.tlog_ppl_id = self._contract.member.ppl_id
    t.tlog_datetime = period.period_start
    t.tlog_shift_datetime = period.period_end
    t.tlog_artc_id = revenue_article_id
    t.tlog_club_id = self._contract.member.ppl_club_id
    t.tlog_ppl_mshp_id = self._contract.ppl_mshp_id


    periodlabel = "{0} to {1}".format(period.period_start, period.period_end)

    # linked periodical articles AB
    for linkedarticle in self._contract.linkedarticles:
        if linkedarticle.pmar_periodical:
            if linkedarticle.pmar_free:
                t.price = 0
            else:
                t.price = linkedarticle.article.artc_price
            t.tlog_artc_id = linkedarticle.artc_id
            t.tlog_comment = "{0}: {1}".format(periodlabel, linkedarticle.article.artc_description)
            t.tlog_evtt_id = 'ab'
            t.tlog_code = 'member_linked_article'
            db_session.add(t)
            # counterbook SIS
            t2 = t
            t2.tlog_evtt_id = 'sis'
            t2.price = t.price * -1
            t2.link(t)
            db_session.add(t2)
            t.tlog_code = None

    db_session.commit()

表示されるのは、初期オブジェクト t のインスタンス化です。リンクされた記事の下で、一連の記事をループして、記事ごとにタイプ AB の新しいトランザクション ログ行を (試みて) 予約します。すべての予約にはカウンター予約 SIS もあります。

データベースには 3 つのレコードが表示されますが、すべて同じプロパティを持ち、すべて tlog_evtt_id 'sis' を持ち、すべての価格が -1 です。したがって、それらはすべて、最後に設定されたプロパティを取得するようです。

SQLAlchemy セッションに追加すると、現在のデータで INSERT が生成され、既存のオブジェクトを編集して再度追加すると、新しいデータで 2 番目の INSERT が生成されると考えました。

要するに、既存のオブジェクトのコピーをデータベースに挿入する SQLAlchemy の方法は何ですか?

4

2 に答える 2

1

この回答によると、コピー コンストラクターが必要です。

class Transactionlog(Base):
    ...
    @classmethod
    def copy(cls, t):
        t_new = cls()
        t_new.tlog_newData = t.tlog_newData
        ...

使用できる別のアイデアは、functools.partialを使用することです。私の例では、デフォルトの SQLAlchemy コンストラクターがあることを前提としています。

data = {'tlog_newData': origin,
        'tlog_ppl_id': self._contract.member.ppl_id,
        ...
       }
make_log = functools.partial(Transactionlog, **data)

# linked periodical articles AB
for linkedarticle in self._contract.linkedarticles:
    if linkedarticle.pmar_periodical:
        t = make_log()
        ...

追加したいオブジェクトごとに新しいインスタンスを実際に作成するので、これは実際にはクリーンな方法だと思います-それはまさにあなたが望むものです。はい、オーバーヘッドはありますが、後でデータベースからそれらのオブジェクトを取得するときにもオーバーヘッドがあります。これは、ORM を使用する代償です。

于 2013-08-28T08:26:14.830 に答える