Skip to content

Commit 0a26343

Browse files
committed
Add custom sqlacodegen generator
1 parent e7fe3d3 commit 0a26343

File tree

4 files changed

+71
-8
lines changed

4 files changed

+71
-8
lines changed

.github/workflows/update-orm.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ jobs:
100100
if: ${{ steps.checkUpdate.outputs.needsUpdate == 'true' }}
101101
run: |
102102
set -eux
103-
sqlacodegen mysql+mysqlconnector://root:[email protected]/ispyb_build --options nojoined --outfile _auto_db_schema.py.in
103+
sqlacodegen --generator declarative_ispyb mysql+mysqlconnector://root:[email protected]/ispyb_build --options nojoined --outfile _auto_db_schema.py.in
104104
# This code produces false positives due to non-deterministic ordering.
105105
# Add an identifier to the file, and only update/PR the changes when the
106106
# identifier indicates the file is out of date.

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ Bug-Tracker = "https://github.com/DiamondLightSource/ispyb-api/issues"
3636
"ispyb.job" = "ispyb.job"
3737
"ispyb.last_data_collections_on" = "ispyb.last_data_collections_on"
3838

39+
[project.entry-points."sqlacodegen.generators"]
40+
declarative_ispyb = "ispyb.generators:DeclarativeIspybGenerator"
41+
3942
[project.entry-points."libtbx.precommit"]
4043
ispyb = "ispyb"
4144

src/ispyb/generators.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
2+
from __future__ import annotations
3+
4+
from collections.abc import Sequence
5+
6+
import inflect
7+
from sqlacodegen.generators import DeclarativeGenerator
8+
from sqlacodegen.models import RelationshipAttribute, RelationshipType
9+
from sqlalchemy import (
10+
MetaData,
11+
)
12+
from sqlalchemy.engine import Connection, Engine
13+
14+
15+
class DeclarativeIspybGenerator(DeclarativeGenerator):
16+
def __init__(
17+
self,
18+
metadata: MetaData,
19+
bind: Connection | Engine,
20+
options: Sequence[str],
21+
*,
22+
indentation: str = " ",
23+
base_class_name: str = "Base",
24+
):
25+
super().__init__(metadata, bind, options, indentation=indentation)
26+
self.base_class_name: str = base_class_name
27+
self.inflect_engine = inflect.engine()
28+
29+
def generate_relationship_name(
30+
self,
31+
relationship: RelationshipAttribute,
32+
global_names: set[str],
33+
local_names: set[str],
34+
) -> None:
35+
# Self referential reverse relationships
36+
preferred_name: str
37+
if (
38+
relationship.type
39+
in (RelationshipType.ONE_TO_MANY, RelationshipType.ONE_TO_ONE)
40+
and relationship.source is relationship.target
41+
and relationship.backref
42+
and relationship.backref.name
43+
):
44+
preferred_name = relationship.backref.name + "_reverse"
45+
else:
46+
preferred_name = relationship.target.table.name
47+
48+
if relationship.constraint:
49+
is_source = relationship.source.table is relationship.constraint.table
50+
if is_source or relationship.type not in (
51+
RelationshipType.ONE_TO_ONE,
52+
RelationshipType.ONE_TO_MANY,
53+
):
54+
column_names = [c.name for c in relationship.constraint.columns]
55+
if len(column_names) == 1 and column_names[0].endswith("_id"):
56+
preferred_name = column_names[0][:-3]
57+
58+
relationship.name = preferred_name

src/ispyb/sqlalchemy/__init__.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,26 @@
1111
from ._auto_db_schema import * # noqa F403; lgtm
1212
from ._auto_db_schema import (
1313
AutoProcProgram,
14-
AutoProcScaling,
1514
ProcessingJob,
1615
__schema_version__,
1716
)
1817

1918
logger = logging.getLogger("ispyb.sqlalchemy")
2019

2120
AutoProcProgram.AutoProcProgramAttachments = relationship(
22-
"AutoProcProgramAttachment", back_populates="AutoProcProgram"
23-
)
24-
AutoProcScaling.AutoProcScalingStatistics = relationship(
25-
"AutoProcScalingStatistics", back_populates="AutoProcScaling"
21+
"AutoProcProgramAttachment",
22+
back_populates="AutoProcProgram",
23+
overlaps="AutoProcProgramAttachment",
2624
)
2725
ProcessingJob.ProcessingJobParameters = relationship(
28-
"ProcessingJobParameter", back_populates="ProcessingJob"
26+
"ProcessingJobParameter",
27+
back_populates="ProcessingJob",
28+
overlaps="ProcessingJobParameter",
2929
)
3030
ProcessingJob.ProcessingJobImageSweeps = relationship(
31-
"ProcessingJobImageSweep", back_populates="ProcessingJob"
31+
"ProcessingJobImageSweep",
32+
back_populates="ProcessingJob",
33+
overlaps="ProcessingJobImageSweep",
3234
)
3335
assert __schema_version__
3436

0 commit comments

Comments
 (0)