Работа с метаданными базы данных¶
: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
Column
Table
Column
Column
Table
Table.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):
... 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
по сравнению с предыдущей версией, на рынке появились
Table
DeclarativeBase.__tablename__
Table
DeclarativeBase.__table__
Eorm_declarative_table_configuration`Ка :class:`_schema.Table
DeclarativeBase.__table__
Declarative with Imperative Table кMapped`F ``int`
str
Integer
String
Использование аннотированной декларативной таблицы (тип аннотированных форм для mapped_column()) Настройка карты типов oOptional[<typ>]``A ``<typ> | None
Union[<typ>, None]
mapped_column.nullable
cmapped_column()
Integer
String
nullable=False
mapped_column()
UUser.addresses``T ``Address.user
relationship()
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
ы