exdrf-dev 0.1.12__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- exdrf_dev/__init__.py +0 -0
- exdrf_dev/__version__.py +24 -0
- exdrf_dev/app/__init__.py +0 -0
- exdrf_dev/app/__main__.py +109 -0
- exdrf_dev/app/main_window.py +50 -0
- exdrf_dev/app/main_window.ui +49 -0
- exdrf_dev/app/main_window_ui.py +69 -0
- exdrf_dev/attr_gen/db/__init__.py +7 -0
- exdrf_dev/attr_gen/db/api.py +7 -0
- exdrf_dev/attr_gen/db/children/__init__.py +7 -0
- exdrf_dev/attr_gen/db/children/api.py +7 -0
- exdrf_dev/attr_gen/db/children/child.py +31 -0
- exdrf_dev/attr_gen/db/children/child_ful.py +0 -0
- exdrf_dev/attr_gen/db/composite_key_models/__init__.py +7 -0
- exdrf_dev/attr_gen/db/composite_key_models/api.py +7 -0
- exdrf_dev/attr_gen/db/composite_key_models/composite_key_model.py +46 -0
- exdrf_dev/attr_gen/db/composite_key_models/composite_key_model_ful.py +0 -0
- exdrf_dev/attr_gen/db/parent_tag_associations/__init__.py +7 -0
- exdrf_dev/attr_gen/db/parent_tag_associations/api.py +7 -0
- exdrf_dev/attr_gen/db/parent_tag_associations/parent_tag_association.py +29 -0
- exdrf_dev/attr_gen/db/parent_tag_associations/parent_tag_association_ful.py +0 -0
- exdrf_dev/attr_gen/db/parents/__init__.py +7 -0
- exdrf_dev/attr_gen/db/parents/api.py +7 -0
- exdrf_dev/attr_gen/db/parents/parent.py +35 -0
- exdrf_dev/attr_gen/db/parents/parent_ful.py +0 -0
- exdrf_dev/attr_gen/db/profiles/__init__.py +7 -0
- exdrf_dev/attr_gen/db/profiles/api.py +7 -0
- exdrf_dev/attr_gen/db/profiles/profile.py +31 -0
- exdrf_dev/attr_gen/db/profiles/profile_ful.py +0 -0
- exdrf_dev/attr_gen/db/related_items/__init__.py +7 -0
- exdrf_dev/attr_gen/db/related_items/api.py +7 -0
- exdrf_dev/attr_gen/db/related_items/related_item.py +33 -0
- exdrf_dev/attr_gen/db/related_items/related_item_ful.py +0 -0
- exdrf_dev/attr_gen/db/tags/__init__.py +7 -0
- exdrf_dev/attr_gen/db/tags/api.py +7 -0
- exdrf_dev/attr_gen/db/tags/tag.py +30 -0
- exdrf_dev/attr_gen/db/tags/tag_ful.py +0 -0
- exdrf_dev/cli.py +89 -0
- exdrf_dev/db/__init__.py +0 -0
- exdrf_dev/db/api.py +10 -0
- exdrf_dev/db/models.py +504 -0
- exdrf_dev/db/populate.py +355 -0
- exdrf_dev/field_ed_show/__init__.py +0 -0
- exdrf_dev/field_ed_show/__main__.py +37 -0
- exdrf_dev/field_ed_show/main_window.py +35 -0
- exdrf_dev/field_ed_show/main_window.ui +229 -0
- exdrf_dev/field_ed_show/main_window_ui.py +206 -0
- exdrf_dev/migrations/6870ef2417bc_.py +138 -0
- exdrf_dev/py.typed +0 -0
- exdrf_dev/pytest_dirs.py +186 -0
- exdrf_dev/qt/__init__.py +0 -0
- exdrf_dev/qt/children/__init__.py +3 -0
- exdrf_dev/qt/children/api.py +8 -0
- exdrf_dev/qt/children/fields/__init__.py +3 -0
- exdrf_dev/qt/children/fields/data_field.py +32 -0
- exdrf_dev/qt/children/fields/id_field.py +29 -0
- exdrf_dev/qt/children/fields/parent_field.py +29 -0
- exdrf_dev/qt/children/fields/parent_id_field.py +28 -0
- exdrf_dev/qt/children/models/__init__.py +3 -0
- exdrf_dev/qt/children/models/children_full_model.py +48 -0
- exdrf_dev/qt/children/models/children_one_col_model.py +39 -0
- exdrf_dev/qt/children/widgets/__init__.py +3 -0
- exdrf_dev/qt/children/widgets/children_editor.py +40 -0
- exdrf_dev/qt/children/widgets/children_editor.ui +103 -0
- exdrf_dev/qt/children/widgets/children_editor_ui.py +124 -0
- exdrf_dev/qt/children/widgets/children_full_list.py +25 -0
- exdrf_dev/qt/children/widgets/children_name_list.py +3 -0
- exdrf_dev/qt/composite_key_models/__init__.py +3 -0
- exdrf_dev/qt/composite_key_models/api.py +16 -0
- exdrf_dev/qt/composite_key_models/fields/__init__.py +3 -0
- exdrf_dev/qt/composite_key_models/fields/description_field.py +30 -0
- exdrf_dev/qt/composite_key_models/fields/key_part1_field.py +34 -0
- exdrf_dev/qt/composite_key_models/fields/key_part2_field.py +31 -0
- exdrf_dev/qt/composite_key_models/fields/related_items_field.py +37 -0
- exdrf_dev/qt/composite_key_models/fields/some_binary_field.py +28 -0
- exdrf_dev/qt/composite_key_models/fields/some_date_field.py +32 -0
- exdrf_dev/qt/composite_key_models/fields/some_enum_field.py +28 -0
- exdrf_dev/qt/composite_key_models/fields/some_float_field.py +35 -0
- exdrf_dev/qt/composite_key_models/fields/some_json_field.py +28 -0
- exdrf_dev/qt/composite_key_models/fields/some_time_field.py +28 -0
- exdrf_dev/qt/composite_key_models/models/__init__.py +3 -0
- exdrf_dev/qt/composite_key_models/models/composite_key_models_full_model.py +79 -0
- exdrf_dev/qt/composite_key_models/models/composite_key_models_one_col_model.py +24 -0
- exdrf_dev/qt/composite_key_models/widgets/__init__.py +3 -0
- exdrf_dev/qt/composite_key_models/widgets/composite_key_models_editor.py +85 -0
- exdrf_dev/qt/composite_key_models/widgets/composite_key_models_editor.ui +165 -0
- exdrf_dev/qt/composite_key_models/widgets/composite_key_models_editor_ui.py +231 -0
- exdrf_dev/qt/composite_key_models/widgets/composite_key_models_full_list.py +29 -0
- exdrf_dev/qt/composite_key_models/widgets/composite_key_models_name_list.py +3 -0
- exdrf_dev/qt/menus.py +120 -0
- exdrf_dev/qt/parent_tag_associations/__init__.py +3 -0
- exdrf_dev/qt/parent_tag_associations/api.py +16 -0
- exdrf_dev/qt/parent_tag_associations/fields/__init__.py +3 -0
- exdrf_dev/qt/parent_tag_associations/fields/parent_id_field.py +29 -0
- exdrf_dev/qt/parent_tag_associations/fields/tag_id_field.py +29 -0
- exdrf_dev/qt/parent_tag_associations/models/__init__.py +3 -0
- exdrf_dev/qt/parent_tag_associations/models/parent_tag_associations_full_model.py +39 -0
- exdrf_dev/qt/parent_tag_associations/models/parent_tag_associations_one_col_model.py +26 -0
- exdrf_dev/qt/parent_tag_associations/widgets/__init__.py +3 -0
- exdrf_dev/qt/parent_tag_associations/widgets/parent_tag_associations_editor.py +73 -0
- exdrf_dev/qt/parent_tag_associations/widgets/parent_tag_associations_editor.ui +62 -0
- exdrf_dev/qt/parent_tag_associations/widgets/parent_tag_associations_editor_ui.py +79 -0
- exdrf_dev/qt/parent_tag_associations/widgets/parent_tag_associations_full_list.py +29 -0
- exdrf_dev/qt/parent_tag_associations/widgets/parent_tag_associations_name_list.py +3 -0
- exdrf_dev/qt/parents/__init__.py +3 -0
- exdrf_dev/qt/parents/api.py +8 -0
- exdrf_dev/qt/parents/fields/__init__.py +3 -0
- exdrf_dev/qt/parents/fields/children_field.py +38 -0
- exdrf_dev/qt/parents/fields/created_at_field.py +32 -0
- exdrf_dev/qt/parents/fields/id_field.py +29 -0
- exdrf_dev/qt/parents/fields/is_active_field.py +28 -0
- exdrf_dev/qt/parents/fields/name_field.py +32 -0
- exdrf_dev/qt/parents/fields/profile_field.py +29 -0
- exdrf_dev/qt/parents/fields/tags_field.py +29 -0
- exdrf_dev/qt/parents/models/__init__.py +3 -0
- exdrf_dev/qt/parents/models/parents_full_model.py +73 -0
- exdrf_dev/qt/parents/models/parents_ocm.py +53 -0
- exdrf_dev/qt/parents/widgets/__init__.py +3 -0
- exdrf_dev/qt/parents/widgets/parents_editor.py +47 -0
- exdrf_dev/qt/parents/widgets/parents_editor.ui +135 -0
- exdrf_dev/qt/parents/widgets/parents_editor_ui.py +162 -0
- exdrf_dev/qt/parents/widgets/parents_full_list.py +25 -0
- exdrf_dev/qt/parents/widgets/parents_name_list.py +3 -0
- exdrf_dev/qt/profiles/__init__.py +3 -0
- exdrf_dev/qt/profiles/api.py +8 -0
- exdrf_dev/qt/profiles/fields/__init__.py +3 -0
- exdrf_dev/qt/profiles/fields/bio_field.py +30 -0
- exdrf_dev/qt/profiles/fields/id_field.py +29 -0
- exdrf_dev/qt/profiles/fields/parent_field.py +29 -0
- exdrf_dev/qt/profiles/fields/parent_id_field.py +30 -0
- exdrf_dev/qt/profiles/models/__init__.py +3 -0
- exdrf_dev/qt/profiles/models/profiles_full_model.py +48 -0
- exdrf_dev/qt/profiles/models/profiles_one_col_model.py +24 -0
- exdrf_dev/qt/profiles/widgets/__init__.py +3 -0
- exdrf_dev/qt/profiles/widgets/profiles_editor.py +47 -0
- exdrf_dev/qt/profiles/widgets/profiles_editor.ui +102 -0
- exdrf_dev/qt/profiles/widgets/profiles_editor_ui.py +125 -0
- exdrf_dev/qt/profiles/widgets/profiles_full_list.py +29 -0
- exdrf_dev/qt/profiles/widgets/profiles_name_list.py +3 -0
- exdrf_dev/qt/related_items/__init__.py +3 -0
- exdrf_dev/qt/related_items/api.py +8 -0
- exdrf_dev/qt/related_items/fields/__init__.py +3 -0
- exdrf_dev/qt/related_items/fields/comp_key_owner_field.py +29 -0
- exdrf_dev/qt/related_items/fields/comp_key_part1_field.py +33 -0
- exdrf_dev/qt/related_items/fields/comp_key_part2_field.py +30 -0
- exdrf_dev/qt/related_items/fields/id_field.py +29 -0
- exdrf_dev/qt/related_items/fields/item_data_field.py +31 -0
- exdrf_dev/qt/related_items/fields/some_int_field.py +33 -0
- exdrf_dev/qt/related_items/models/__init__.py +3 -0
- exdrf_dev/qt/related_items/models/related_items_full_model.py +59 -0
- exdrf_dev/qt/related_items/models/related_items_one_col_model.py +24 -0
- exdrf_dev/qt/related_items/widgets/__init__.py +3 -0
- exdrf_dev/qt/related_items/widgets/related_items_editor.py +49 -0
- exdrf_dev/qt/related_items/widgets/related_items_editor.ui +124 -0
- exdrf_dev/qt/related_items/widgets/related_items_editor_ui.py +167 -0
- exdrf_dev/qt/related_items/widgets/related_items_full_list.py +29 -0
- exdrf_dev/qt/related_items/widgets/related_items_name_list.py +3 -0
- exdrf_dev/qt/tags/__init__.py +3 -0
- exdrf_dev/qt/tags/api.py +8 -0
- exdrf_dev/qt/tags/fields/__init__.py +3 -0
- exdrf_dev/qt/tags/fields/id_field.py +29 -0
- exdrf_dev/qt/tags/fields/name_field.py +31 -0
- exdrf_dev/qt/tags/fields/parents_field.py +29 -0
- exdrf_dev/qt/tags/models/__init__.py +3 -0
- exdrf_dev/qt/tags/models/tags_full_model.py +46 -0
- exdrf_dev/qt/tags/models/tags_one_col_model.py +24 -0
- exdrf_dev/qt/tags/widgets/__init__.py +3 -0
- exdrf_dev/qt/tags/widgets/tags_editor.py +47 -0
- exdrf_dev/qt/tags/widgets/tags_editor.ui +91 -0
- exdrf_dev/qt/tags/widgets/tags_editor_ui.py +112 -0
- exdrf_dev/qt/tags/widgets/tags_full_list.py +25 -0
- exdrf_dev/qt/tags/widgets/tags_name_list.py +3 -0
- exdrf_dev/qt_gen/db/__init__.py +7 -0
- exdrf_dev/qt_gen/db/api.py +16 -0
- exdrf_dev/qt_gen/db/children/__init__.py +7 -0
- exdrf_dev/qt_gen/db/children/api.py +29 -0
- exdrf_dev/qt_gen/db/children/fields/__init__.py +7 -0
- exdrf_dev/qt_gen/db/children/fields/fld_data.py +48 -0
- exdrf_dev/qt_gen/db/children/fields/fld_id.py +47 -0
- exdrf_dev/qt_gen/db/children/fields/fld_parent.py +95 -0
- exdrf_dev/qt_gen/db/children/fields/fld_parent_id.py +46 -0
- exdrf_dev/qt_gen/db/children/fields/single_f.py +67 -0
- exdrf_dev/qt_gen/db/children/models/__init__.py +7 -0
- exdrf_dev/qt_gen/db/children/models/child_ful.py +147 -0
- exdrf_dev/qt_gen/db/children/models/child_ocm.py +99 -0
- exdrf_dev/qt_gen/db/children/widgets/__init__.py +7 -0
- exdrf_dev/qt_gen/db/children/widgets/child_editor.py +90 -0
- exdrf_dev/qt_gen/db/children/widgets/child_editor.ui +139 -0
- exdrf_dev/qt_gen/db/children/widgets/child_editor_ui.py +115 -0
- exdrf_dev/qt_gen/db/children/widgets/child_list.py +83 -0
- exdrf_dev/qt_gen/db/children/widgets/child_selector.py +122 -0
- exdrf_dev/qt_gen/db/children/widgets/child_tv.html.j2 +19 -0
- exdrf_dev/qt_gen/db/children/widgets/child_tv.py +173 -0
- exdrf_dev/qt_gen/db/composite_key_models/__init__.py +7 -0
- exdrf_dev/qt_gen/db/composite_key_models/api.py +33 -0
- exdrf_dev/qt_gen/db/composite_key_models/fields/__init__.py +7 -0
- exdrf_dev/qt_gen/db/composite_key_models/fields/fld_description.py +46 -0
- exdrf_dev/qt_gen/db/composite_key_models/fields/fld_key_part1.py +50 -0
- exdrf_dev/qt_gen/db/composite_key_models/fields/fld_key_part2.py +49 -0
- exdrf_dev/qt_gen/db/composite_key_models/fields/fld_related_items.py +95 -0
- exdrf_dev/qt_gen/db/composite_key_models/fields/fld_some_binary.py +45 -0
- exdrf_dev/qt_gen/db/composite_key_models/fields/fld_some_date.py +47 -0
- exdrf_dev/qt_gen/db/composite_key_models/fields/fld_some_enum.py +52 -0
- exdrf_dev/qt_gen/db/composite_key_models/fields/fld_some_float.py +50 -0
- exdrf_dev/qt_gen/db/composite_key_models/fields/fld_some_json.py +45 -0
- exdrf_dev/qt_gen/db/composite_key_models/fields/fld_some_time.py +44 -0
- exdrf_dev/qt_gen/db/composite_key_models/fields/single_f.py +63 -0
- exdrf_dev/qt_gen/db/composite_key_models/models/__init__.py +7 -0
- exdrf_dev/qt_gen/db/composite_key_models/models/composite_key_model_ful.py +188 -0
- exdrf_dev/qt_gen/db/composite_key_models/models/composite_key_model_ocm.py +126 -0
- exdrf_dev/qt_gen/db/composite_key_models/widgets/__init__.py +7 -0
- exdrf_dev/qt_gen/db/composite_key_models/widgets/composite_key_model_editor.py +99 -0
- exdrf_dev/qt_gen/db/composite_key_models/widgets/composite_key_model_editor.ui +349 -0
- exdrf_dev/qt_gen/db/composite_key_models/widgets/composite_key_model_editor_ui.py +282 -0
- exdrf_dev/qt_gen/db/composite_key_models/widgets/composite_key_model_list.py +85 -0
- exdrf_dev/qt_gen/db/composite_key_models/widgets/composite_key_model_selector.py +126 -0
- exdrf_dev/qt_gen/db/composite_key_models/widgets/composite_key_model_tv.html.j2 +35 -0
- exdrf_dev/qt_gen/db/composite_key_models/widgets/composite_key_model_tv.py +231 -0
- exdrf_dev/qt_gen/db/parent_tag_associations/__init__.py +7 -0
- exdrf_dev/qt_gen/db/parent_tag_associations/api.py +33 -0
- exdrf_dev/qt_gen/db/parent_tag_associations/fields/__init__.py +7 -0
- exdrf_dev/qt_gen/db/parent_tag_associations/fields/fld_parent_id.py +47 -0
- exdrf_dev/qt_gen/db/parent_tag_associations/fields/fld_tag_id.py +47 -0
- exdrf_dev/qt_gen/db/parent_tag_associations/fields/single_f.py +68 -0
- exdrf_dev/qt_gen/db/parent_tag_associations/models/__init__.py +7 -0
- exdrf_dev/qt_gen/db/parent_tag_associations/models/parent_tag_association_ful.py +147 -0
- exdrf_dev/qt_gen/db/parent_tag_associations/models/parent_tag_association_ocm.py +95 -0
- exdrf_dev/qt_gen/db/parent_tag_associations/widgets/__init__.py +7 -0
- exdrf_dev/qt_gen/db/parent_tag_associations/widgets/parent_tag_association_editor.py +106 -0
- exdrf_dev/qt_gen/db/parent_tag_associations/widgets/parent_tag_association_editor.ui +90 -0
- exdrf_dev/qt_gen/db/parent_tag_associations/widgets/parent_tag_association_editor_ui.py +90 -0
- exdrf_dev/qt_gen/db/parent_tag_associations/widgets/parent_tag_association_list.py +91 -0
- exdrf_dev/qt_gen/db/parent_tag_associations/widgets/parent_tag_association_selector.py +130 -0
- exdrf_dev/qt_gen/db/parent_tag_associations/widgets/parent_tag_association_tv.html.j2 +11 -0
- exdrf_dev/qt_gen/db/parent_tag_associations/widgets/parent_tag_association_tv.py +177 -0
- exdrf_dev/qt_gen/db/parents/__init__.py +7 -0
- exdrf_dev/qt_gen/db/parents/api.py +29 -0
- exdrf_dev/qt_gen/db/parents/fields/__init__.py +7 -0
- exdrf_dev/qt_gen/db/parents/fields/fld_children.py +102 -0
- exdrf_dev/qt_gen/db/parents/fields/fld_created_at.py +48 -0
- exdrf_dev/qt_gen/db/parents/fields/fld_id.py +47 -0
- exdrf_dev/qt_gen/db/parents/fields/fld_is_active.py +47 -0
- exdrf_dev/qt_gen/db/parents/fields/fld_name.py +48 -0
- exdrf_dev/qt_gen/db/parents/fields/fld_profile.py +94 -0
- exdrf_dev/qt_gen/db/parents/fields/fld_tags.py +94 -0
- exdrf_dev/qt_gen/db/parents/fields/single_f.py +60 -0
- exdrf_dev/qt_gen/db/parents/models/__init__.py +7 -0
- exdrf_dev/qt_gen/db/parents/models/parent_ful.py +165 -0
- exdrf_dev/qt_gen/db/parents/models/parent_ocm.py +95 -0
- exdrf_dev/qt_gen/db/parents/widgets/__init__.py +7 -0
- exdrf_dev/qt_gen/db/parents/widgets/parent_editor.py +85 -0
- exdrf_dev/qt_gen/db/parents/widgets/parent_editor.ui +252 -0
- exdrf_dev/qt_gen/db/parents/widgets/parent_editor_ui.py +186 -0
- exdrf_dev/qt_gen/db/parents/widgets/parent_list.py +83 -0
- exdrf_dev/qt_gen/db/parents/widgets/parent_selector.py +122 -0
- exdrf_dev/qt_gen/db/parents/widgets/parent_tv.html.j2 +31 -0
- exdrf_dev/qt_gen/db/parents/widgets/parent_tv.py +204 -0
- exdrf_dev/qt_gen/db/profiles/__init__.py +7 -0
- exdrf_dev/qt_gen/db/profiles/api.py +29 -0
- exdrf_dev/qt_gen/db/profiles/fields/__init__.py +7 -0
- exdrf_dev/qt_gen/db/profiles/fields/fld_bio.py +45 -0
- exdrf_dev/qt_gen/db/profiles/fields/fld_id.py +47 -0
- exdrf_dev/qt_gen/db/profiles/fields/fld_parent.py +94 -0
- exdrf_dev/qt_gen/db/profiles/fields/fld_parent_id.py +48 -0
- exdrf_dev/qt_gen/db/profiles/fields/single_f.py +60 -0
- exdrf_dev/qt_gen/db/profiles/models/__init__.py +7 -0
- exdrf_dev/qt_gen/db/profiles/models/profile_ful.py +129 -0
- exdrf_dev/qt_gen/db/profiles/models/profile_ocm.py +89 -0
- exdrf_dev/qt_gen/db/profiles/widgets/__init__.py +7 -0
- exdrf_dev/qt_gen/db/profiles/widgets/db/__init__.py +1 -0
- exdrf_dev/qt_gen/db/profiles/widgets/db/profile.py +26 -0
- exdrf_dev/qt_gen/db/profiles/widgets/profile_editor.py +90 -0
- exdrf_dev/qt_gen/db/profiles/widgets/profile_editor.ui +139 -0
- exdrf_dev/qt_gen/db/profiles/widgets/profile_editor_ui.py +115 -0
- exdrf_dev/qt_gen/db/profiles/widgets/profile_list.py +83 -0
- exdrf_dev/qt_gen/db/profiles/widgets/profile_selector.py +126 -0
- exdrf_dev/qt_gen/db/profiles/widgets/profile_tv.html.j2 +19 -0
- exdrf_dev/qt_gen/db/profiles/widgets/profile_tv.py +179 -0
- exdrf_dev/qt_gen/db/related_items/__init__.py +7 -0
- exdrf_dev/qt_gen/db/related_items/api.py +33 -0
- exdrf_dev/qt_gen/db/related_items/fields/__init__.py +7 -0
- exdrf_dev/qt_gen/db/related_items/fields/fld_comp_key_owner.py +96 -0
- exdrf_dev/qt_gen/db/related_items/fields/fld_comp_key_part1.py +49 -0
- exdrf_dev/qt_gen/db/related_items/fields/fld_comp_key_part2.py +48 -0
- exdrf_dev/qt_gen/db/related_items/fields/fld_id.py +47 -0
- exdrf_dev/qt_gen/db/related_items/fields/fld_item_data.py +46 -0
- exdrf_dev/qt_gen/db/related_items/fields/fld_some_int.py +51 -0
- exdrf_dev/qt_gen/db/related_items/fields/single_f.py +57 -0
- exdrf_dev/qt_gen/db/related_items/models/__init__.py +7 -0
- exdrf_dev/qt_gen/db/related_items/models/related_item_ful.py +148 -0
- exdrf_dev/qt_gen/db/related_items/models/related_item_ocm.py +102 -0
- exdrf_dev/qt_gen/db/related_items/widgets/__init__.py +7 -0
- exdrf_dev/qt_gen/db/related_items/widgets/related_item_editor.py +88 -0
- exdrf_dev/qt_gen/db/related_items/widgets/related_item_editor.ui +209 -0
- exdrf_dev/qt_gen/db/related_items/widgets/related_item_editor_ui.py +183 -0
- exdrf_dev/qt_gen/db/related_items/widgets/related_item_list.py +86 -0
- exdrf_dev/qt_gen/db/related_items/widgets/related_item_selector.py +126 -0
- exdrf_dev/qt_gen/db/related_items/widgets/related_item_tv.html.j2 +27 -0
- exdrf_dev/qt_gen/db/related_items/widgets/related_item_tv.py +212 -0
- exdrf_dev/qt_gen/db/tags/__init__.py +7 -0
- exdrf_dev/qt_gen/db/tags/api.py +29 -0
- exdrf_dev/qt_gen/db/tags/fields/__init__.py +7 -0
- exdrf_dev/qt_gen/db/tags/fields/fld_id.py +47 -0
- exdrf_dev/qt_gen/db/tags/fields/fld_name.py +47 -0
- exdrf_dev/qt_gen/db/tags/fields/fld_parents.py +95 -0
- exdrf_dev/qt_gen/db/tags/fields/single_f.py +60 -0
- exdrf_dev/qt_gen/db/tags/models/__init__.py +7 -0
- exdrf_dev/qt_gen/db/tags/models/tag_ful.py +133 -0
- exdrf_dev/qt_gen/db/tags/models/tag_ocm.py +87 -0
- exdrf_dev/qt_gen/db/tags/widgets/__init__.py +7 -0
- exdrf_dev/qt_gen/db/tags/widgets/tag_editor.py +83 -0
- exdrf_dev/qt_gen/db/tags/widgets/tag_editor.ui +134 -0
- exdrf_dev/qt_gen/db/tags/widgets/tag_editor_ui.py +114 -0
- exdrf_dev/qt_gen/db/tags/widgets/tag_list.py +83 -0
- exdrf_dev/qt_gen/db/tags/widgets/tag_selector.py +122 -0
- exdrf_dev/qt_gen/db/tags/widgets/tag_tv.html.j2 +15 -0
- exdrf_dev/qt_gen/db/tags/widgets/tag_tv.py +168 -0
- exdrf_dev/qt_gen/menus.py +121 -0
- exdrf_dev/qt_gen/plugins.py +484 -0
- exdrf_dev/qt_gen/router.py +594 -0
- exdrf_dev/remove_empty_file_named_file.py +129 -0
- exdrf_dev/select_model_show/__init__.py +0 -0
- exdrf_dev/select_model_show/__main__.py +60 -0
- exdrf_dev/select_model_show/main_window.py +45 -0
- exdrf_dev-0.1.12.dist-info/METADATA +37 -0
- exdrf_dev-0.1.12.dist-info/RECORD +335 -0
- exdrf_dev-0.1.12.dist-info/WHEEL +5 -0
- exdrf_dev-0.1.12.dist-info/top_level.txt +3 -0
- exdrf_dev_tests/__init__.py +0 -0
- exdrf_dev_tests/qt_test/__init__.py +0 -0
- exdrf_dev_tests/qt_test/children_test/__init__.py +0 -0
- exdrf_dev_tests/qt_test/children_test/fields_test/__init__.py +0 -0
- exdrf_dev_tests/qt_test/children_test/models_test/__init__.py +0 -0
- exdrf_dev_tests/qt_test/children_test/models_test/children_full_test.py +362 -0
- exdrf_dev_tests/qt_test/children_test/models_test/children_ocm_test.py +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# This file was automatically generated using the exdrf_gen package.
|
|
2
|
+
# Source: exdrf_gen_al2at.creator -> c/api.py.j2
|
|
3
|
+
# Don't change it manually.
|
|
4
|
+
|
|
5
|
+
# exdrf-keep-start more_content ------------------------------------------------
|
|
6
|
+
|
|
7
|
+
# exdrf-keep-end more_content --------------------------------------------------
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from attrs import define, field
|
|
4
|
+
|
|
5
|
+
# exdrf-keep-start other_imports ----------------------------------------------
|
|
6
|
+
|
|
7
|
+
# exdrf-keep-end other_imports ------------------------------------------------
|
|
8
|
+
|
|
9
|
+
# exdrf-keep-start other_globals ----------------------------------------------
|
|
10
|
+
|
|
11
|
+
# exdrf-keep-end other_globals ------------------------------------------------
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@define
|
|
15
|
+
class Tag:
|
|
16
|
+
# exdrf-keep-start other_attributes ---------------------------------------
|
|
17
|
+
|
|
18
|
+
# exdrf-keep-end other_attributes -----------------------------------------
|
|
19
|
+
name: Optional[str] = field(default=None)
|
|
20
|
+
parents: Optional[list[str]] = field(default=None)
|
|
21
|
+
id: Optional[int] = field(default=None)
|
|
22
|
+
|
|
23
|
+
# exdrf-keep-start extra_class_content -------------------------------------
|
|
24
|
+
|
|
25
|
+
# exdrf-keep-end extra_class_content ---------------------------------------
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# exdrf-keep-start more_content -----------------------------------------------
|
|
29
|
+
|
|
30
|
+
# exdrf-keep-end more_content -------------------------------------------------
|
|
File without changes
|
exdrf_dev/cli.py
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
import subprocess
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
from dotenv import load_dotenv
|
|
7
|
+
|
|
8
|
+
from exdrf_al.click_support.auto_db_migration import auto_db_migration
|
|
9
|
+
from exdrf_al.click_support.downgrade_db import downgrade_db
|
|
10
|
+
from exdrf_al.click_support.list_db_version import list_db_versions
|
|
11
|
+
from exdrf_al.click_support.set_db_version import set_db_version
|
|
12
|
+
from exdrf_al.click_support.upgrade_db import upgrade_db
|
|
13
|
+
from exdrf_dev.__version__ import __version__
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@click.group()
|
|
17
|
+
@click.option("--debug/--no-debug", default=False)
|
|
18
|
+
@click.version_option(__version__, prog_name="exdrf-dev")
|
|
19
|
+
def cli(debug: bool):
|
|
20
|
+
logging.basicConfig(
|
|
21
|
+
level=logging.DEBUG if debug else logging.INFO,
|
|
22
|
+
format="[%(levelname)s] %(message)s",
|
|
23
|
+
datefmt="%Y-%m-%d %H:%M:%S",
|
|
24
|
+
)
|
|
25
|
+
logging.debug("Debug mode is on")
|
|
26
|
+
os.environ["CURDIR"] = os.getcwd()
|
|
27
|
+
|
|
28
|
+
load_dotenv(override=True)
|
|
29
|
+
click.echo("=" * 80)
|
|
30
|
+
_print_env("Environment variables after .env")
|
|
31
|
+
click.echo("=" * 80)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _print_env(title: str = "Environment variables"):
|
|
35
|
+
click.echo(title)
|
|
36
|
+
for key in sorted(os.environ.keys()):
|
|
37
|
+
value = os.environ[key]
|
|
38
|
+
if len(value) > 50:
|
|
39
|
+
click.echo(f"{key}:")
|
|
40
|
+
for part in value.split(";"):
|
|
41
|
+
click.echo(f" {part}")
|
|
42
|
+
else:
|
|
43
|
+
click.echo(f"{key}: {value}")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@cli.command()
|
|
47
|
+
def print_env():
|
|
48
|
+
"""Print the environment variables."""
|
|
49
|
+
_print_env()
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@cli.command()
|
|
53
|
+
@click.argument("args", nargs=-1)
|
|
54
|
+
def run(args):
|
|
55
|
+
"""Run the exdrf-dev application with provided arguments."""
|
|
56
|
+
click.echo(f"Running exdrf-dev with arguments: {args}")
|
|
57
|
+
try:
|
|
58
|
+
final_args = []
|
|
59
|
+
for a in args:
|
|
60
|
+
if a.startswith("env:"):
|
|
61
|
+
env_var = a[4:]
|
|
62
|
+
env_value = os.environ.get(env_var)
|
|
63
|
+
if env_value is None:
|
|
64
|
+
click.echo(f"Env. variable '{env_var}' not found.", err=True)
|
|
65
|
+
return
|
|
66
|
+
a = env_value
|
|
67
|
+
final_args.append(a)
|
|
68
|
+
|
|
69
|
+
result = subprocess.run(
|
|
70
|
+
final_args, check=True, text=True, capture_output=True, shell=True
|
|
71
|
+
)
|
|
72
|
+
click.echo(result.stdout)
|
|
73
|
+
if result.stderr:
|
|
74
|
+
click.echo(result.stderr, err=True)
|
|
75
|
+
except subprocess.CalledProcessError as e:
|
|
76
|
+
click.echo(f"Command failed with exit code {e.returncode}", err=True)
|
|
77
|
+
click.echo(e.stderr, err=True)
|
|
78
|
+
except FileNotFoundError:
|
|
79
|
+
click.echo("Command not found", err=True)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
cli.add_command(auto_db_migration)
|
|
83
|
+
cli.add_command(list_db_versions)
|
|
84
|
+
cli.add_command(set_db_version)
|
|
85
|
+
cli.add_command(upgrade_db)
|
|
86
|
+
cli.add_command(downgrade_db)
|
|
87
|
+
|
|
88
|
+
if __name__ == "__main__":
|
|
89
|
+
cli()
|
exdrf_dev/db/__init__.py
ADDED
|
File without changes
|
exdrf_dev/db/api.py
ADDED
exdrf_dev/db/models.py
ADDED
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
import enum
|
|
3
|
+
from typing import Any, Dict, List, Optional
|
|
4
|
+
|
|
5
|
+
from sqlalchemy import (
|
|
6
|
+
JSON,
|
|
7
|
+
Boolean,
|
|
8
|
+
Date,
|
|
9
|
+
DateTime,
|
|
10
|
+
Enum,
|
|
11
|
+
Float,
|
|
12
|
+
ForeignKey,
|
|
13
|
+
ForeignKeyConstraint,
|
|
14
|
+
Integer,
|
|
15
|
+
LargeBinary,
|
|
16
|
+
PrimaryKeyConstraint,
|
|
17
|
+
String,
|
|
18
|
+
Time,
|
|
19
|
+
create_engine,
|
|
20
|
+
)
|
|
21
|
+
from sqlalchemy.orm import (
|
|
22
|
+
Mapped,
|
|
23
|
+
mapped_column,
|
|
24
|
+
relationship,
|
|
25
|
+
sessionmaker,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
from exdrf_al.base import Base
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class StatusEnum(enum.Enum):
|
|
32
|
+
"""Enumeration for various status values."""
|
|
33
|
+
|
|
34
|
+
PENDING = "pending"
|
|
35
|
+
PROCESSING = "processing"
|
|
36
|
+
COMPLETED = "completed"
|
|
37
|
+
FAILED = "failed"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# --- Association Table for Many-to-Many ---
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ParentTagAssociation(Base):
|
|
44
|
+
"""Association object for the many-to-many relationship between Parent and
|
|
45
|
+
Tag.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
__tablename__ = "parent_tag_association"
|
|
49
|
+
__table_args__ = (
|
|
50
|
+
PrimaryKeyConstraint("parent_id", "tag_id"),
|
|
51
|
+
{"info": {"label": """(concat "Parent:" parent_id " Tag:" tag_id)"""}},
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
parent_id: Mapped[int] = mapped_column(
|
|
55
|
+
Integer,
|
|
56
|
+
ForeignKey("parents.id"),
|
|
57
|
+
primary_key=True,
|
|
58
|
+
doc="Foreign key to the parents table.",
|
|
59
|
+
)
|
|
60
|
+
tag_id: Mapped[int] = mapped_column(
|
|
61
|
+
Integer,
|
|
62
|
+
ForeignKey("tags.id"),
|
|
63
|
+
primary_key=True,
|
|
64
|
+
doc="Foreign key to the tags table.",
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
def __repr__(self) -> str:
|
|
68
|
+
return (
|
|
69
|
+
f"<ParentTagAssociation(parent_id={self.parent_id}, tag_id={self.tag_id})>"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# --- Model Definitions ---
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class Parent(Base):
|
|
77
|
+
"""Represents a parent entity with various relationships."""
|
|
78
|
+
|
|
79
|
+
__tablename__ = "parents"
|
|
80
|
+
__table_args__ = {"info": {"label": """(concat "ID:" id " Name:" name)"""}}
|
|
81
|
+
|
|
82
|
+
id: Mapped[int] = mapped_column(
|
|
83
|
+
Integer, primary_key=True, doc="Primary key for the parent."
|
|
84
|
+
)
|
|
85
|
+
name: Mapped[str] = mapped_column(
|
|
86
|
+
String(100),
|
|
87
|
+
index=True,
|
|
88
|
+
doc="Name of the parent.",
|
|
89
|
+
info={
|
|
90
|
+
"min_length": 1,
|
|
91
|
+
"multiline": False,
|
|
92
|
+
"visible": True,
|
|
93
|
+
"sortable": True,
|
|
94
|
+
"filterable": True,
|
|
95
|
+
},
|
|
96
|
+
)
|
|
97
|
+
created_at: Mapped[datetime.datetime] = mapped_column(
|
|
98
|
+
DateTime,
|
|
99
|
+
default=datetime.datetime.utcnow,
|
|
100
|
+
doc="Timestamp when the parent was created.",
|
|
101
|
+
info={
|
|
102
|
+
"min": datetime.datetime(2020, 1, 1, 0, 0),
|
|
103
|
+
"max": datetime.datetime(2030, 12, 31, 23, 59),
|
|
104
|
+
},
|
|
105
|
+
)
|
|
106
|
+
is_active: Mapped[bool] = mapped_column(
|
|
107
|
+
Boolean,
|
|
108
|
+
default=True,
|
|
109
|
+
doc="Flag indicating if the parent is active.",
|
|
110
|
+
info={
|
|
111
|
+
"true_str": "Active",
|
|
112
|
+
"false_str": "Inactive",
|
|
113
|
+
},
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
# One-to-Many relationship with Child
|
|
117
|
+
children: Mapped[List["Child"]] = relationship(
|
|
118
|
+
"Child",
|
|
119
|
+
back_populates="parent",
|
|
120
|
+
cascade="all, delete-orphan",
|
|
121
|
+
info={
|
|
122
|
+
"doc": "Children associated with this parent.",
|
|
123
|
+
"direction": "OneToMany",
|
|
124
|
+
},
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
# One-to-One relationship with Profile
|
|
128
|
+
profile: Mapped[Optional["Profile"]] = relationship(
|
|
129
|
+
"Profile",
|
|
130
|
+
back_populates="parent",
|
|
131
|
+
uselist=False,
|
|
132
|
+
cascade="all, delete-orphan",
|
|
133
|
+
info={
|
|
134
|
+
"doc": "Profile associated with this parent (one-to-one).",
|
|
135
|
+
"direction": "OneToOne",
|
|
136
|
+
},
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
# Many-to-Many relationship with Tag
|
|
140
|
+
tags: Mapped[List["Tag"]] = relationship(
|
|
141
|
+
"Tag",
|
|
142
|
+
secondary="parent_tag_association",
|
|
143
|
+
back_populates="parents",
|
|
144
|
+
info={
|
|
145
|
+
"doc": "Tags associated with this parent (many-to-many).",
|
|
146
|
+
"direction": "ManyToMany",
|
|
147
|
+
},
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
def __repr__(self) -> str:
|
|
151
|
+
return f"<Parent(id={self.id}, name='{self.name}')>"
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class Child(Base):
|
|
155
|
+
"""Represents a child entity linked to a parent."""
|
|
156
|
+
|
|
157
|
+
__tablename__ = "children"
|
|
158
|
+
__table_args__ = {
|
|
159
|
+
"info": {
|
|
160
|
+
"label": """
|
|
161
|
+
(concat "ID:" id " Parent " parent.name " Data:" data)
|
|
162
|
+
"""
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
id: Mapped[int] = mapped_column(
|
|
167
|
+
Integer, primary_key=True, doc="Primary key for the child."
|
|
168
|
+
)
|
|
169
|
+
data: Mapped[Optional[str]] = mapped_column(
|
|
170
|
+
String,
|
|
171
|
+
doc="Some data associated with the child.",
|
|
172
|
+
info={
|
|
173
|
+
"min_length": 1,
|
|
174
|
+
"max_length": 200,
|
|
175
|
+
"multiline": True,
|
|
176
|
+
"visible": True,
|
|
177
|
+
"sortable": True,
|
|
178
|
+
"filterable": True,
|
|
179
|
+
},
|
|
180
|
+
)
|
|
181
|
+
parent_id: Mapped[int] = mapped_column(
|
|
182
|
+
Integer,
|
|
183
|
+
ForeignKey("parents.id"),
|
|
184
|
+
doc="Foreign key linking to the parent.",
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
# Many-to-One relationship with Parent
|
|
188
|
+
parent: Mapped["Parent"] = relationship(
|
|
189
|
+
"Parent",
|
|
190
|
+
back_populates="children",
|
|
191
|
+
info={
|
|
192
|
+
"doc": "The parent associated with this child.",
|
|
193
|
+
"direction": "ManyToOne",
|
|
194
|
+
},
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
def __repr__(self) -> str:
|
|
198
|
+
return f"<Child(id={self.id}, data='{self.data}', parent_id={self.parent_id})>"
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
class Profile(Base):
|
|
202
|
+
"""Represents a profile entity linked one-to-one with a parent."""
|
|
203
|
+
|
|
204
|
+
__tablename__ = "profiles"
|
|
205
|
+
__table_args__ = {"info": {"label": """(concat "ID:" id " Bio:" bio)"""}}
|
|
206
|
+
|
|
207
|
+
id: Mapped[int] = mapped_column(
|
|
208
|
+
Integer, primary_key=True, doc="Primary key for the profile."
|
|
209
|
+
)
|
|
210
|
+
bio: Mapped[Optional[str]] = mapped_column(
|
|
211
|
+
String, doc="Biography text for the profile."
|
|
212
|
+
)
|
|
213
|
+
parent_id: Mapped[int] = mapped_column(
|
|
214
|
+
Integer,
|
|
215
|
+
ForeignKey("parents.id"),
|
|
216
|
+
unique=True, # Ensures one-to-one relationship at the DB level
|
|
217
|
+
doc="Foreign key linking to the parent (must be unique).",
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
# One-to-One relationship back to Parent
|
|
221
|
+
parent: Mapped["Parent"] = relationship(
|
|
222
|
+
"Parent",
|
|
223
|
+
back_populates="profile",
|
|
224
|
+
info={
|
|
225
|
+
"doc": "The parent associated with this profile.",
|
|
226
|
+
"direction": "OneToOne",
|
|
227
|
+
},
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
def __repr__(self) -> str:
|
|
231
|
+
return f"<Profile(id={self.id}, parent_id={self.parent_id})>"
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
class Tag(Base):
|
|
235
|
+
"""Represents a tag entity for many-to-many relationships."""
|
|
236
|
+
|
|
237
|
+
__tablename__ = "tags"
|
|
238
|
+
__table_args__ = {"info": {"label": """(concat "ID:" id " Name:" name)"""}}
|
|
239
|
+
|
|
240
|
+
id: Mapped[int] = mapped_column(
|
|
241
|
+
Integer, primary_key=True, doc="Primary key for the tag."
|
|
242
|
+
)
|
|
243
|
+
name: Mapped[str] = mapped_column(
|
|
244
|
+
String(50), unique=True, index=True, doc="Unique name of the tag."
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
# Many-to-Many relationship back to Parent
|
|
248
|
+
parents: Mapped[List["Parent"]] = relationship(
|
|
249
|
+
"Parent",
|
|
250
|
+
secondary="parent_tag_association",
|
|
251
|
+
back_populates="tags",
|
|
252
|
+
info={
|
|
253
|
+
"doc": "Parents associated with this tag.",
|
|
254
|
+
"direction": "ManyToMany",
|
|
255
|
+
},
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
def __repr__(self) -> str:
|
|
259
|
+
return f"<Tag(id={self.id}, name='{self.name}')>"
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
class CompositeKeyModel(Base):
|
|
263
|
+
"""Demonstrates a model with a composite primary key and various data
|
|
264
|
+
types.
|
|
265
|
+
"""
|
|
266
|
+
|
|
267
|
+
__tablename__ = "comp_key_models"
|
|
268
|
+
|
|
269
|
+
# Composite Primary Key
|
|
270
|
+
key_part1: Mapped[str] = mapped_column(
|
|
271
|
+
String(50),
|
|
272
|
+
primary_key=True,
|
|
273
|
+
doc="First part of the composite primary key (string).",
|
|
274
|
+
)
|
|
275
|
+
key_part2: Mapped[int] = mapped_column(
|
|
276
|
+
Integer,
|
|
277
|
+
primary_key=True,
|
|
278
|
+
doc="Second part of the composite primary key (integer).",
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
description: Mapped[Optional[str]] = mapped_column(
|
|
282
|
+
String,
|
|
283
|
+
doc="A description for this record.",
|
|
284
|
+
info={
|
|
285
|
+
"multiline": True,
|
|
286
|
+
},
|
|
287
|
+
)
|
|
288
|
+
some_float: Mapped[Optional[float]] = mapped_column(
|
|
289
|
+
Float,
|
|
290
|
+
doc="A floating-point number.",
|
|
291
|
+
info={
|
|
292
|
+
"min": 0.0,
|
|
293
|
+
"max": 100.0,
|
|
294
|
+
"precision": 2,
|
|
295
|
+
"scale": 2,
|
|
296
|
+
"unit": "units",
|
|
297
|
+
"unit_symbol": "u",
|
|
298
|
+
},
|
|
299
|
+
)
|
|
300
|
+
some_date: Mapped[Optional[datetime.date]] = mapped_column(
|
|
301
|
+
Date,
|
|
302
|
+
doc="A date value.",
|
|
303
|
+
info={
|
|
304
|
+
"min": datetime.date(2020, 1, 1),
|
|
305
|
+
"max": datetime.date(2030, 12, 31),
|
|
306
|
+
},
|
|
307
|
+
)
|
|
308
|
+
some_time: Mapped[Optional[datetime.time]] = mapped_column(
|
|
309
|
+
Time,
|
|
310
|
+
doc="A time value.",
|
|
311
|
+
)
|
|
312
|
+
some_enum: Mapped[Optional[StatusEnum]] = mapped_column(
|
|
313
|
+
Enum(StatusEnum), doc="An enum value representing status."
|
|
314
|
+
)
|
|
315
|
+
some_json: Mapped[Optional[Dict[str, Any]]] = mapped_column(
|
|
316
|
+
JSON, doc="A JSON object."
|
|
317
|
+
)
|
|
318
|
+
some_binary: Mapped[Optional[bytes]] = mapped_column(
|
|
319
|
+
LargeBinary,
|
|
320
|
+
doc="Binary data.",
|
|
321
|
+
info={
|
|
322
|
+
"visible": False,
|
|
323
|
+
"sortable": False,
|
|
324
|
+
"filterable": False,
|
|
325
|
+
"mime_type": "application/octet-stream",
|
|
326
|
+
},
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
# One-to-Many relationship with RelatedItem using composite foreign key
|
|
330
|
+
related_items: Mapped[List["RelatedItem"]] = relationship(
|
|
331
|
+
"RelatedItem",
|
|
332
|
+
back_populates="comp_key_owner",
|
|
333
|
+
cascade="all, delete-orphan",
|
|
334
|
+
foreign_keys="[RelatedItem.comp_key_part1, RelatedItem.comp_key_part2]",
|
|
335
|
+
info={
|
|
336
|
+
"doc": "Items related to this composite key model.",
|
|
337
|
+
"direction": "OneToMany",
|
|
338
|
+
},
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
__table_args__ = (
|
|
342
|
+
PrimaryKeyConstraint("key_part1", "key_part2", name="composite_pk"),
|
|
343
|
+
{"info": {"label": """(concat "Description:" description)"""}},
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
def __repr__(self) -> str:
|
|
347
|
+
return (
|
|
348
|
+
f"<CompositeKeyModel(key_part1='{self.key_part1}', "
|
|
349
|
+
f"key_part2={self.key_part2})>"
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
class RelatedItem(Base):
|
|
354
|
+
"""Model related to CompositeKeyModel via its composite key."""
|
|
355
|
+
|
|
356
|
+
__tablename__ = "related_items"
|
|
357
|
+
|
|
358
|
+
id: Mapped[int] = mapped_column(
|
|
359
|
+
Integer, primary_key=True, doc="Primary key for the related item."
|
|
360
|
+
)
|
|
361
|
+
item_data: Mapped[Optional[str]] = mapped_column(
|
|
362
|
+
String(200), doc="Data specific to the related item."
|
|
363
|
+
)
|
|
364
|
+
some_int: Mapped[Optional[int]] = mapped_column(
|
|
365
|
+
Integer,
|
|
366
|
+
doc="An integer value associated with the related item.",
|
|
367
|
+
info={
|
|
368
|
+
"min": 0,
|
|
369
|
+
"max": 1000,
|
|
370
|
+
"unit": "units",
|
|
371
|
+
"unit_symbol": "u",
|
|
372
|
+
},
|
|
373
|
+
)
|
|
374
|
+
|
|
375
|
+
# Composite Foreign Key parts
|
|
376
|
+
comp_key_part1: Mapped[str] = mapped_column(
|
|
377
|
+
String(50), doc="Foreign key part 1 referencing CompositeKeyModel."
|
|
378
|
+
)
|
|
379
|
+
comp_key_part2: Mapped[int] = mapped_column(
|
|
380
|
+
Integer, doc="Foreign key part 2 referencing CompositeKeyModel."
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
# Many-to-One relationship back to CompositeKeyModel
|
|
384
|
+
comp_key_owner: Mapped["CompositeKeyModel"] = relationship(
|
|
385
|
+
"CompositeKeyModel",
|
|
386
|
+
back_populates="related_items",
|
|
387
|
+
foreign_keys=[comp_key_part1, comp_key_part2],
|
|
388
|
+
info={
|
|
389
|
+
"doc": "The owner model with the composite key.",
|
|
390
|
+
"direction": "ManyToOne",
|
|
391
|
+
},
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
# Define the composite foreign key constraint
|
|
395
|
+
__table_args__ = (
|
|
396
|
+
ForeignKeyConstraint(
|
|
397
|
+
["comp_key_part1", "comp_key_part2"],
|
|
398
|
+
["comp_key_models.key_part1", "comp_key_models.key_part2"],
|
|
399
|
+
name="related_item_composite_fk",
|
|
400
|
+
),
|
|
401
|
+
{"info": {"label": """(concat "ID:" id)"""}},
|
|
402
|
+
)
|
|
403
|
+
|
|
404
|
+
def __repr__(self) -> str:
|
|
405
|
+
return (
|
|
406
|
+
f"<RelatedItem(id={self.id}, "
|
|
407
|
+
f"key1='{self.comp_key_part1}', key2={self.comp_key_part2})>"
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
def get_dev_engine():
|
|
412
|
+
"""Creates an in-memory SQLite database engine for development/testing."""
|
|
413
|
+
engine = create_engine("sqlite:///:memory:")
|
|
414
|
+
Base.metadata.create_all(engine)
|
|
415
|
+
return engine
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
def get_populated_dev_engine(engine=None):
|
|
419
|
+
"""Creates an in-memory SQLite database engine and populates it with
|
|
420
|
+
sample data.
|
|
421
|
+
"""
|
|
422
|
+
if engine is None:
|
|
423
|
+
engine = get_dev_engine()
|
|
424
|
+
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
|
425
|
+
|
|
426
|
+
with SessionLocal() as session:
|
|
427
|
+
# Create instances
|
|
428
|
+
tag1 = Tag(name="Urgent")
|
|
429
|
+
tag2 = Tag(name="Project Alpha")
|
|
430
|
+
|
|
431
|
+
parent1 = Parent(name="Parent One")
|
|
432
|
+
parent1.profile = Profile(bio="Profile for Parent One")
|
|
433
|
+
parent1.children.append(Child(data="Child A data"))
|
|
434
|
+
parent1.children.append(Child(data="Child B data"))
|
|
435
|
+
parent1.tags.extend([tag1, tag2])
|
|
436
|
+
|
|
437
|
+
parent2 = Parent(name="Parent Two", is_active=False)
|
|
438
|
+
parent2.children.append(Child(data="Child C data"))
|
|
439
|
+
parent2.tags.append(tag1)
|
|
440
|
+
|
|
441
|
+
comp_key_obj1 = CompositeKeyModel(
|
|
442
|
+
key_part1="ITEM_A",
|
|
443
|
+
key_part2=101,
|
|
444
|
+
description="First composite item",
|
|
445
|
+
some_float=3.14,
|
|
446
|
+
some_date=datetime.date(2023, 1, 15),
|
|
447
|
+
some_time=datetime.time(10, 30, 0),
|
|
448
|
+
some_enum=StatusEnum.PROCESSING,
|
|
449
|
+
some_json={"config": True, "values": [1, 2, 3]},
|
|
450
|
+
some_binary=b"\x01\x02\x03\x04",
|
|
451
|
+
)
|
|
452
|
+
comp_key_obj1.related_items.append(
|
|
453
|
+
RelatedItem(item_data="Related data 1", some_int=42)
|
|
454
|
+
)
|
|
455
|
+
comp_key_obj1.related_items.append(
|
|
456
|
+
RelatedItem(item_data="Related data 2", some_int=84)
|
|
457
|
+
)
|
|
458
|
+
|
|
459
|
+
comp_key_obj2 = CompositeKeyModel(
|
|
460
|
+
key_part1="ITEM_B",
|
|
461
|
+
key_part2=202,
|
|
462
|
+
description="Second composite item",
|
|
463
|
+
some_enum=StatusEnum.COMPLETED,
|
|
464
|
+
)
|
|
465
|
+
|
|
466
|
+
# Add to session and commit
|
|
467
|
+
session.add_all([parent1, parent2, comp_key_obj1, comp_key_obj2])
|
|
468
|
+
session.commit()
|
|
469
|
+
|
|
470
|
+
return engine
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
def print_db_content(engine):
|
|
474
|
+
"""Prints the content of all tables defined in Base.metadata."""
|
|
475
|
+
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
|
476
|
+
models_to_print = [
|
|
477
|
+
Parent,
|
|
478
|
+
Child,
|
|
479
|
+
Profile,
|
|
480
|
+
Tag,
|
|
481
|
+
CompositeKeyModel,
|
|
482
|
+
RelatedItem,
|
|
483
|
+
]
|
|
484
|
+
|
|
485
|
+
with SessionLocal() as session:
|
|
486
|
+
for model_cls in models_to_print:
|
|
487
|
+
table_name = model_cls.__tablename__
|
|
488
|
+
print(f"\n--- Table: {table_name} ---")
|
|
489
|
+
try:
|
|
490
|
+
instances = session.query(model_cls).all()
|
|
491
|
+
if instances:
|
|
492
|
+
for instance in instances:
|
|
493
|
+
print(instance)
|
|
494
|
+
else:
|
|
495
|
+
print("(empty)")
|
|
496
|
+
except Exception as e:
|
|
497
|
+
print(f"Error querying table {table_name}: {e}")
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
if __name__ == "__main__":
|
|
501
|
+
# Example usage
|
|
502
|
+
engine = get_populated_dev_engine()
|
|
503
|
+
print_db_content(engine)
|
|
504
|
+
print("Database populated and printed successfully.")
|