SQL Alchemy =========== `SQL Alchemy `_ is an Object Relational Mapper (ORM) for Python The SQL Alchemy generator will generate Python code for mapping an Object Model to a SQL Database. The structure of the SQL Database structure is consistent with the one generated by :doc:`sqltable` In principle, two styles of mappings are possible: 1. Declarative, in which SQLA-style classes are generated, with combined mappings 2. Imperative, in which separate mappings are created for a pre-existing object model, such as one created by the existing python or pydantic generators Currently only the Declarative style is fully supported Overview -------- Declarative Mode ^^^^^^^^^^^^^^^^ See `declarative mapping docs `_ on SQL Alchemy site Given input such as: .. code:: yaml Person: is_a: NamedThing description: >- A person (alive, dead, undead, or fictional). class_uri: schema:Person mixins: - HasAliases slots: - primary_email - birth_date - age_in_years - gender - current_address - has_employment_history - has_familial_relationships - has_medical_history Event: slots: - started_at_time - ended_at_time - duration - is_current MedicalEvent: is_a: Event slots: - in_location - diagnosis - procedure The generated Python will look like: .. code:: python class Person(NamedThing): """ A person (alive, dead, undead, or fictional). """ __tablename__ = 'Person' primary_email = Column(Text()) birth_date = Column(Text()) age_in_years = Column(Integer()) gender = Column(Enum('nonbinary man', 'nonbinary woman', 'transgender woman', 'transgender man', 'cisgender man', 'cisgender woman', name='GenderType')) id = Column(Text(), primary_key=True) name = Column(Text()) description = Column(Text()) image = Column(Text()) Container_id = Column(Text(), ForeignKey('Container.id')) current_address_id = Column(Text(), ForeignKey('Address.id')) current_address = relationship("Address", uselist=False) has_employment_history = relationship( "EmploymentEvent", foreign_keys="[EmploymentEvent.Person_id]") has_familial_relationships = relationship( "FamilialRelationship", foreign_keys="[FamilialRelationship.Person_id]") has_medical_history = relationship( "MedicalEvent", foreign_keys="[MedicalEvent.Person_id]") aliases_rel = relationship( "Person_alias" ) aliases = association_proxy("aliases_rel", "alias", creator=lambda x_: Person_alias(alias=x_)) has_news_events = relationship( "NewsEvent", secondary="Person_has_news_event") The first line of the class is a `Declarative Table `_ declaration, the maps the class to the table name. This should correspond to the table from the SQL DDL generator. The use of the relationship construct is described in `mapped properties `_ section of the SQLA docs. Note that class slots are "rolled down". Docs ---- Command Line ^^^^^^^^^^^^ .. currentmodule:: linkml.generators.sqlalchemygen .. click:: linkml.generators.sqlalchemygen:cli :prog: gen-sqla :nested: short Code ^^^^ .. autoclass:: SQLAlchemyGenerator :members: serialize