Обеспечение проверки на уровне класса модели в sqlalchemy - PullRequest
0 голосов
/ 13 ноября 2018

Я пытаюсь вставить данные в свою таблицу postgres после прочтения файла xlsx.Мне нужно проверить данные листа xlsx, прежде чем я вставлю их в свою таблицу.

Я работаю над pandas dataframe df = pd.read_excel('/Users/ankitg3-mac/Downloads/medical_plans/%s' % filename)

Я использую sqlalchemy в качестве инструмента ORM.

Мой класс модели:

    class MedicalPlan(Base):
        __tablename__ = "medical_plans"

        id = Column(Integer, nullable=False , primary_key=True)
        issuer_id = Column(Integer, ForeignKey('issuers.id'), nullable=False)
        service_area_id = Column(Integer)
        name = Column(String)
        on_exchange = Column(Boolean)
        off_exchange = Column(Boolean)
        starting_percentage_fpl = Column(REAL, nullable=False , default=0)
        ending_percentage_fpl = Column(REAL, nullable=False, default=0)
        metal_level_name = Column(String)
        network_type = Column(String)
        type = Column(String)
        is_age_29_plan = Column(Boolean)
        original_medicare = Column(Boolean)
        default_bhp = Column(Boolean, default=False)
        sort_rank_override = Column(Integer)
        recommended = Column(Boolean, default=False)
        comparable_individual_plan_id_trash = Column(Integer)
        group_or_individual_plan_type = Column(String)
        hios_plan_identifier = Column(String)

Я делаю массовую вставку с использованием списка словарей.

conn.execute(MedicalPlan.__table__.insert(), medicalPlan_dict)

Мой medicalPlan_dict выглядит следующим образом:

[{u'default_bhp': False, u'price_period': u'Monthly', u'plan_description': '', u'sbc_download_url': '', u'price_note': '', u'starting_percentage_fpl': 0, u'is_uhc_plan': False, 'issuer_id': 440, u'part_b_deductible': '', u'promotional_label': '', u'metal_level_name': u'Silver', u'network_url': '', u'group_or_individual_plan_type': u'Group', u'treatment_cost_calculator_url': '', u'hios_plan_identifier': u'99844RI1800001', u'original_medicare': False, u'part_d_prescription_coverage': '', u'recommended': False, u'off_exchange': True, u'is_age_29_plan': False, u'type': u'MetalPlan', u'ending_percentage_fpl': 0, u'plan_detail_footer': '', u'formulary_url': '', u'plan_detail_items': '', u'highlight_6': '', u'highlight_4': '', u'highlight_5': '', u'hsa_eligible': False, u'highlight_3': u'PCP 20% coinsurance', u'highlight_1': u'Silver', u'name': u'WI 80 INDEMNITY 18 OPTION 1 SILVER RX $10/45/90/25%', u'network_description': '', u'plan_detail_header': '', 'service_area_id': 1, u'data_sourced_from': u'uhc', u'plan_year': 2018, u'highlight_2': u'Indemnity', u'on_exchange': False, u'network_type': u'Indemnity'}, {u'default_bhp': False, u'price_period': u'Monthly', u'plan_description': '', u'sbc_download_url': '', u'price_note': '', u'starting_percentage_fpl': 0, u'is_uhc_plan': False, 'issuer_id': 484, u'part_b_deductible': '', u'promotional_label': '', u'metal_level_name': u'Silver', u'network_url': '', u'group_or_individual_plan_type': u'Group', u'treatment_cost_calculator_url': '', u'hios_plan_identifier': u'99806CAAUSJ-TMP1', u'original_medicare': False, u'part_d_prescription_coverage': '', u'recommended': False, u'off_exchange': True, u'is_age_29_plan': False, u'type': u'MetalPlan', u'ending_percentage_fpl': 0, u'plan_detail_footer': '', u'formulary_url': '', u'plan_detail_items': '', u'highlight_6': '', u'highlight_4': '', u'highlight_5': '', u'hsa_eligible': False, u'highlight_3': u'PCP 20% coinsurance', u'highlight_1': u'Silver', u'name': u'WI 80 INDEMNITY 18 OPTION 1 SILVER RX $10/45/90/25%', u'network_description': '', u'plan_detail_header': '', 'service_area_id': 1, u'data_sourced_from': u'uhc', u'plan_year': 2018, u'highlight_2': u'Indemnity', u'on_exchange': False, u'network_type': u'Indemnity'}, {u'default_bhp': False, u'price_period': u'Monthly', u'plan_description': '', u'sbc_download_url': '', u'price_note': '', u'starting_percentage_fpl': 0, u'is_uhc_plan': False, 'issuer_id': 440, u'part_b_deductible': '', u'promotional_label': '', u'metal_level_name': u'Silver', u'network_url': '', u'group_or_individual_plan_type': u'Group', u'treatment_cost_calculator_url': '', u'hios_plan_identifier': u'99844RI1800002', u'original_medicare': False, u'part_d_prescription_coverage': '', u'recommended': False, u'off_exchange': True, u'is_age_29_plan': False, u'type': u'MetalPlan', u'ending_percentage_fpl': 0, u'plan_detail_footer': '', u'formulary_url': '', u'plan_detail_items': '', u'highlight_6': '', u'highlight_4': '', u'highlight_5': '', u'hsa_eligible': False, u'highlight_3': u'PCP 20% coinsurance', u'highlight_1': u'Silver', u'name': u'WI 80 INDEMNITY 18 OPTION 1 SILVER RX $10/45/90/25%', u'network_description': '', u'plan_detail_header': '', 'service_area_id': 1, u'data_sourced_from': u'uhc', u'plan_year': 2018, u'highlight_2': u'Indemnity', u'on_exchange': False, u'network_type': u'Indemnity'}]

Мне нужно проверить данные, прежде чем вставить их в свою таблицу.Я прочитал о проверках sqlalchemy и попробовал что-то подобное ниже, предполагая, что он позаботится о проверках на уровне модели.

@validates('hios_plan_identifier')
    def validate_hios_plan_identifier(self, key, hios_plan_identifier):
        assert '/\A(\d{5}[A-Z]{2}[a-zA-Z0-9]{3,7}-TMP|\d{5}[A-Z]{2}\d{3,7}(\-?\d{2})*)\z/,' in hios_plan_identifier
        return hios_plan_identifier

Мне нужно добавить несколько проверок для каждой переменной.Только строки, которые проходят, должны быть вставлены.

Я не уверен, как работать с проверками на уровне модели.Как я могу этого добиться.

1 Ответ

0 голосов
/ 22 ноября 2018

Два варианта:

  • Добавьте CheckConstraint в столбец и добавьте туда свое регулярное выражение, см. https://www.postgresql.org/docs/9.3/functions-matching.html.Это работает любым способом, которым вы выбрасываете данные в базу данных.
  • Используйте проверку на основе событий, как показано здесь , создайте список объектов, которые вы хотите вставить, и используйте session.add_all() для пакетной вставки.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...