Creating Tables¶
examples/features/orm/_0_create_tables.py¶
from __future__ import annotations
from sqlalchemy import (
Column,
ForeignKey,
MetaData,
String,
text,
)
from sqlalchemy.orm import (
DeclarativeBase,
Mapped,
mapped_column,
relationship,
)
from examples.config import (
DEFAULT_SCHEMA_NAME,
ENGINE,
SQL_ALCHEMY,
)
# For more information on ORM table definitions, check out:
# https://docs.sqlalchemy.org/en/20/orm/quickstart.html#orm-quick-start
# 1. Ensure that the schema exists
SQL_ALCHEMY.create_schema(engine=ENGINE, schema=DEFAULT_SCHEMA_NAME)
# 2. Use the schema to define the metadata_obj, which is used in the `Base` class
metadata_obj = MetaData(schema=DEFAULT_SCHEMA_NAME)
class Base(DeclarativeBase):
metadata = metadata_obj
# 3. Inherit from the `Base` class when defining your tables
class User(Base):
__tablename__ = "user"
id: Mapped[int] = mapped_column(primary_key=True)
first_name: Mapped[str] = mapped_column(String(30))
last_name: Mapped[str] = mapped_column(String(30))
# For relationship, the column type must use the class name, but the
# `back_populates` uses the name of the table in the database.
email_addresses: Mapped[list[EmailAddress]] = relationship(
back_populates="user", cascade="all, delete-orphan"
)
def first_email(self) -> Column[str] | None:
if self.email_addresses:
return self.email_addresses[0].email_address
return None
def __repr__(self) -> str:
return f"User(id={self.id!r}, first_name={self.first_name!r}, last_name={self.last_name!r})"
class EmailAddress(Base):
__tablename__ = "email_address"
id: Mapped[int] = mapped_column(primary_key=True)
user_id: Mapped[int] = mapped_column(ForeignKey("user.id"), nullable=False)
email_address = Column(String(255))
user: Mapped[User] = relationship(back_populates="email_addresses")
def __repr__(self) -> str:
return f"Address(id={self.id!r}, email_address={self.email_address!r})"
# 4. Create all tables
Base.metadata.create_all(ENGINE)
# 5. Verify that the tables have been created
query = f"""
SELECT TABLE_NAME
FROM SYS.EXA_ALL_TABLES
WHERE TABLE_SCHEMA = '{DEFAULT_SCHEMA_NAME}'
ORDER BY TABLE_NAME
"""
with ENGINE.connect() as con:
results = con.execute(text(query)).fetchall()
if __name__ == "__main__":
print(f"Tables in schema={DEFAULT_SCHEMA_NAME}: {results}")