OK so you are explicitly worrying about a one-to-many relationship that should be one-to-one, or vice versa, that is, you aren't worried about FKs or remote_side setting up the entirely wrong M2O / O2M for a relationship.
However luckily, the only issue with any of this is having that argument available and fortunately it looks like I got around to adding info to relationship(), so you can check / validate whatever you want, including if the "direction" got set up as expected or whatever other things you want to put into that info. here's o2o:
from sqlalchemy import Column
from sqlalchemy import create_engine
from sqlalchemy import event
from sqlalchemy import ForeignKey
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy.orm import Session
Base = declarative_base()
class A(Base):
__tablename__ = "a"
id = Column(Integer, primary_key=True)
data = Column(String)
b = relationship("B", back_populates="a", uselist=False)
class B(Base):
__tablename__ = "b"
id = Column(Integer, primary_key=True)
a_id = Column(ForeignKey("
a.id"))
data = Column(String)
a = relationship("A", back_populates="b", info={"one_to_one": True})
@event.listens_for(Base, "mapper_configured", propagate=True)
def _validate(mapper, cls):
for rel in mapper.relationships:
assert rel.mapper.attrs[rel.back_populates].uselist == (
)
e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)
s = Session(e)
s.add(A(b=B()))
s.commit()