Работа с метаданными базы данных

:term:`database metadata`W

MetaData Table Column М

**Читатели **ORM, оставайтесь с нами!

Table`Ка :class:.Table` к

Установить

:class:`_schema.Table`Когда w

Table Table Использование декларативных форм ORM для определения метаданных таблицы reflection с

MetaData`Wh :term:`facade Table i

>>> from sqlalchemy import MetaData
>>> metadata_obj = MetaData()

Table user_account address user_account Table е

>>> from sqlalchemy import Table, Column, Integer, String
>>> user_table = Table(
...     "user_account",
...     metadata_obj,
...     Column("id", Integer, primary_key=True),
...     Column("name", String(30)),
...     Column("fullname", String),
... )

user_account user_table W

``Table``Com

:class:`_schema.Table`Мы c

Table DDL Table В

Объявление простых ограничений

Column`В результате, ``user_table` по сравнению Column.primary_key с предыдущими Column годами, PrimaryKeyConstraint были Table.primary_key получены Table следующие результаты

>>> user_table.primary_key
PrimaryKeyConstraint(Column('id', Integer(), table=<user_account>, primary_key=True, nullable=False))

ForeignKeyConstraint foreign key constraint C

ForeignKey address user 0

>>> from sqlalchemy import ForeignKey
>>> address_table = Table(
...     "address",
...     metadata_obj,
...     Column("id", Integer, primary_key=True),
...     Column("user_id", ForeignKey("user_account.id"), nullable=False),
...     Column("email_address", String, nullable=False),
... )

:paramref:`_schema.Column.nullable`В результате, по сравнению с предыдущей версией, на рынке появились

Совет

Column Column Integer user_account.id а

user``В т ``address .

Передача DDL в базу данных

Table Column Constraint ы

DDL`В результате, :meth:`_schema.MetaData.create_all по сравнению MetaData с предыдущими Engine годами, были получены следующие результаты

>>> metadata_obj.create_all(engine)
{execsql}BEGIN (implicit)
PRAGMA main.table_...info("user_account")
...
PRAGMA main.table_...info("address")
...
CREATE TABLE user_account (
    id INTEGER NOT NULL,
    name VARCHAR(30),
    fullname VARCHAR,
    PRIMARY KEY (id)
)
...
CREATE TABLE address (
    id INTEGER NOT NULL,
    user_id INTEGER NOT NULL,
    email_address VARCHAR NOT NULL,
    PRIMARY KEY (id),
    FOREIGN KEY(user_id) REFERENCES user_account (id)
)
...
COMMIT

Приведенный выше процесс создания DDL включает несколько специфических для SQLite операторов PRAGMA, которые проверяют существование каждой таблицы перед выдачей команды CREATE. Вся серия шагов также включена в пару BEGIN/COMMIT, что позволяет использовать транзакционный DDL.

user address C

В качестве параметра MetaData выступае MetaData.drop_all() т

Использование декларативных форм ORM для определения метаданных таблицы

Table`Когд :term:`mapped declarative Table а

Создание декларативной базы

DeclarativeBase а

>>> from sqlalchemy.orm import DeclarativeBase
>>> class Base(DeclarativeBase):
...     pass

Base``A ``Base Table b

MetaData`Сай :class:.MetaData` DeclarativeBase.metadata Table MetaData т

>>> Base.metadata
MetaData()

registry`Сай :class:.MetaData` registry registry DeclarativeBase.registry т

>>> Base.registry
<sqlalchemy.orm.decl_api.registry object at 0x...>

Объявление сопоставленных классов

Base user_account address User Address PEP 484 Mapped W

>>> from typing import List
>>> from typing import Optional
>>> from sqlalchemy.orm import Mapped
>>> from sqlalchemy.orm import mapped_column
>>> from sqlalchemy.orm import relationship

>>> class User(Base):
...     __tablename__ = "user_account"
...
...     id: Mapped[int] = mapped_column(primary_key=True)
...     name: Mapped[str] = mapped_column(String(30))
...     fullname: Mapped[Optional[str]]
...
...     addresses: Mapped[List["Address"]] = relationship(back_populates="user")
...
...     def __repr__(self) -> str:
...         return f"User(id={self.id!r}, name={self.name!r}, fullname={self.fullname!r})"

>>> class Address(Base):
...     __tablename__ = "address"
...
...     id: Mapped[int] = mapped_column(primary_key=True)
...     email_address: Mapped[str]
...     user_id = mapped_column(ForeignKey("user_account.id"))
...
...     user: Mapped[User] = relationship(back_populates="addresses")
...
...     def __repr__(self) -> str:
...         return f"Address(id={self.id!r}, email_address={self.email_address!r})"

User``В результате, ``Address по сравнению с предыдущей версией, на рынке появились

Выдача DDL в базу данных из ORM отображения

MetaData Передача DDL в базу данных user address MetaData DeclarativeBase.metadata MetaData.create_all() к

>>> Base.metadata.create_all(engine)
{execsql}BEGIN (implicit)
PRAGMA main.table_...info("user_account")
...
PRAGMA main.table_...info("address")
...
COMMIT

Отражение в таблице

Table а

Совет

Для использования SQLAlchemy с уже существующей базой данных не требуется применять рефлексию. Вполне типично, что приложение SQLAlchemy объявляет все метаданные явно на языке Python, так что их структура соответствует структуре существующей базы данных. Структура метаданных также не должна включать таблицы, столбцы и другие ограничения и конструкции существующей базы данных, которые не нужны для работы локального приложения.

Table`Ка ``some_table` Table MetaData Column Constraint Engine Table.autoload_with к

>>> some_table = Table("some_table", metadata_obj, autoload_with=engine)
{execsql}BEGIN (implicit)
PRAGMA main.table_...info("some_table")
[raw sql] ()
SELECT sql FROM  (SELECT * FROM sqlite_master UNION ALL   SELECT * FROM sqlite_temp_master) WHERE name = ? AND type in ('table', 'view')
[raw sql] ('some_table',)
PRAGMA main.foreign_key_list("some_table")
...
PRAGMA main.index_list("some_table")
...
ROLLBACK{stop}

``some_table``На сайт Column Table е

>>> some_table
Table('some_table', MetaData(),
    Column('x', INTEGER(), table=<some_table>),
    Column('y', INTEGER(), table=<some_table>),
    schema=None)

См.также

:ref:`metadata_reflection_toplevel`Re

:ref:`orm_declarative_reflected`Fo

Следующие шаги

Session ы

Вернуться на верх