クライアントから MS Access DB ファイル (.accdb) を受け取り、declarative_base クラスでテーブルと列を記述する必要があります。テーブルコンストラクターでわかるように、列の1つに整数値があり、別のテーブル(外部キー)の別の列と「1対多」の関係があります。しかし、実際には、この外部キーには単一の整数値ではなく、セミコロンで区切られた数値の文字列が格納されています。この手法は「複数値フィールド」と呼ばれます。実際、これは連想テーブルを使用しない「多対多」の関係です。
非常に単純化されたスキーム:
Persons
-------------
id - Integer
name - String
vacancy_id - Integer (multi-value, Foreign key of Vacancies.id)
Vacancies
-------------
id - Integer
vacancy_name - String
declarative_base 親クラスを使用してクラスをテーブルにマップしようとしました。しかし、連想テーブルなしで「多対多」の関係を宣言する方法が見つかりません。今、私はそのようなコードを持っています。
Base = declarative_base()
class Vacancy(Base):
__tablename__ = 'Vacancies'
id = sa.Column(sa.Integer, name='id', primary_key=True, autoincrement=True)
vacancy_name = sa.Column(sa.String(255), name='vacancy_name')
class Person(Base):
__tablename__ = 'Persons'
id = sa.Column(sa.Integer, name='id', primary_key=True, autoincrement=True)
name = sa.Column(sa.String(255), name='name')
vacancy_id = sa.Column(sa.Integer, ForeignKey(Vacancy.id), name='vacancy_id')
vacancies = relationship(Vacancy)
リクエスト中 Person 私は奇妙な行動をしています:
- vacancy_id が指定されていない場合、Person.vacancy は None として取得されます。
- vacancy_id が単一の値 (つまり "1") として指定されている場合、Person.vacances で Vacancy クラスの単一のオブジェクトを取得します。
- vacancy_id が複数の値 (つまり "1;2;3") として指定されている場合、Person.vacancy では None も取得されます。
もちろん、生の Person.vacancy_id をリクエストし、それをセミコロンで分割して、ID のリストを含む欠員を取得するリクエストを行うことができます。
しかし、SqlAlchemy は「複数値フィールド」を処理できるのでしょうか? そして、そのようなファイルを扱う最良の方法は何ですか?
更新 現在、複数値の列を自動的に解析するために、次の回避策を作成しました。これを Persons クラスに追加する必要があります。
@orm.reconstructor
def load_on_init(self):
if self.vacancy_id:
ids = self.vacancy_id.split(';')
self.vacancies = [x for x in Vacancy.query.filter(Vacancy.id.in_(ids)).all()]
else:
self.vacancies = []
Vacancy クラスには次の属性が必要です。
query = DBSession.query_property()
最後に、クラス内で使用するためのセッションを準備する必要があります。
engine = create_engine(CONNECTION_URI)
DBSession = scoped_session(sessionmaker(bind=engine))
Base = declarative_base()