web-dev-qa-db-ja.com

周期的なインポートや副作用を作成せずにORMモジュールを分割する

序文

リレーショナル不動産データベース用のORMライブラリがあります。使用されているフレームワークはpeeweeです。ライブラリには、それぞれが個別のテーブルを表す最大60個のモデルが含まれています。モデルは、XMLに基づく(事前定義された、独自仕様の)不動産データ構造を表します。 XMLドキュメントのルートを表すimmobilie(不動産)と呼ばれる最上位テーブルが1つあります。

各モデルは、かなりの量のコードを含むクラスメソッドfrom_dom(cls, dom)およびfrom_dict(cls, dictionary)とメソッドto_dom(self)およびto_dict(self)を定義しています。

問題

ライブラリはそのままの状態で正常に機能しますが、モジュールには現在10255行のコードが含まれているため、読み取りと保守が非常に困難です。

最初のアイデア

したがって、私の考えは、モジュールをいくつかの小さなモジュールに分割し、それぞれを1つのモデルに対応させることでした。ただし、これにより次の問題が発生します。

1)peeweeでは、それぞれのモデル定義でそれぞれの外部キーのモデルを設定する必要があります。プレゼンテーションを簡単にするために、次のことを前提とします。

class Parent(Model):

    @property
    def semi_orphans(self):
         return Child.select().where(
             (Child.mom == self & Child.dad >> None)
             | (Child.mom >> None & Child.dad == self))


class Child(model):
    mom = ForeignKeyField(Parent)
    dad = ForeignKeyField(Parent)

したがって、参照モデルはそれぞれのモデル定義にインポートする必要があります。

2)semi_orphansプロパティの例で明らかになるように、ほとんどすべての参照モデルは、特定の選択方法の参照モデルも知っている必要があります。

これは、コードの一部ですでにテストしたように、解決できない循環インポートを作成します。

第二のアイデア

したがって、別のモールの独自のサブクラスに後方参照メソッドを外部委託できると思いました。ただし、これにより、次のような場合は使用できなくなります。

some_child = Child.get()
semi_orphans = some_child.mom.semi_orphans

some_child.momsemi_orphansメソッドなしで基本モデルを返すため、これによりAttributeErrorがトリガーされます。

質問

私は何かを見落としているか?循環的な依存関係を取り除く方法がないため、ライブラリを小さなコンポーネントに分割してコードの品質と保守性を向上させることは本当に不可能ですか?

4
Richard Neumann

さらに検討した後、モデルを実際のORMモデルに分割し始め、JSONとXML DOMの(逆)シリアライゼーションをそれぞれミックスインクラスを使用して独自のパッケージに外部委託しました。また、予想される複合キーを返さない外部キーの問題ではなく、ベースモデルも解決しました。 peeweeには、知らなかったDeferredForeignKeyクラスがあります。後で(ミックスインを使用して)複合モデルを設定するためにそれを使用すると、この問題を解決できます。

0
Richard Neumann