Работа с метаданными базы данных¶
:term:`database metadata`W
Установить¶
: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
ColumnTableColumnColumnTableTable.c->>> user_table.c.name Column('name', String(length=30), table=<user_account>) >>> user_table.c.keys() ['id', 'name', 'fullname']
См.также
Table Column Описание баз данных с помощью метаданных Объекты типов данных SQL е
Объявление простых ограничений¶
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`В результате, по сравнению с предыдущей версией, на рынке появились
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):
... passBase``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 по сравнению с предыдущей версией, на рынке появились
TableDeclarativeBase.__tablename__TableDeclarativeBase.__table__Eorm_declarative_table_configuration`Ка :class:`_schema.Table
DeclarativeBase.__table__Declarative with Imperative Table кMapped`F ``int`strIntegerStringИспользование аннотированной декларативной таблицы (тип аннотированных форм для mapped_column()) Настройка карты типов oOptional[<typ>]``A ``<typ> | NoneUnion[<typ>, None]mapped_column.nullablecmapped_column()IntegerStringnullable=Falsemapped_column()UUser.addresses``T ``Address.userrelationship()relationship()Работа с объектами, связанными с ORM w``__init__()``C
>>> sandy = User(name="sandy", fullname="Sandy Cheeks")
__init__()``Н :ref:`orm_declarative_native_dataclasses` ``__init__()аВстретились <<<0>>
__init__()__repr__()dataclasses >
Выдача 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)Следующие шаги¶
Session ы