Я ищу правильный способ управления рекурсивным объектом с использованием sqlalchemy.
Синтаксис Column_property выглядит очень многообещающе, но я не мог заставить его загрузить Дети. < /p>
Ниже приведен mre: < /p>
from sqlalchemy import (
Column,
ForeignKey,
Integer,
create_engine,
select,
)
from sqlalchemy.orm import (
backref,
column_property,
declarative_base,
relationship,
remote,
Session,
)
from sqlalchemy.sql.expression import null
from testcontainers.postgres import PostgresContainer
Base = declarative_base()
class Category(Base):
__tablename__ = "categories"
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey("categories.id"), index=True, nullable=True)
children = relationship(
"Category",
primaryjoin=(id == remote(parent_id)),
lazy="select",
backref=backref(
"parent",
primaryjoin=(remote(id) == parent_id),
lazy="select",
),
)
deep_children = column_property(null())
def build_deep_children_expr():
cte_query = select(Category.id).cte(recursive=True, name="descendants_cte")
parent_query = select(Category).where(Category.parent_id == cte_query.c.id)
cte_query = cte_query.union_all(parent_query)
return select(cte_query).scalar_subquery()
Category.deep_children = column_property(build_deep_children_expr())
if __name__ == "__main__":
# Use a temporary PostgreSQL container
with PostgresContainer("postgres:16.1") as postgres:
database_url = postgres.get_connection_url(driver="psycopg")
engine = create_engine(database_url, echo=True)
Base.metadata.create_all(engine)
session = Session(engine)
# Build a hierarchy of categories:
# root (0)
# ├─ (1)
# └─ (2)
# ├─ (3)
# ├─ (4)
# └─ (5)
# ├─ (6)
# └─ (7)
root = Category(
id=0,
children=[
Category(id=1),
Category(
id=2,
children=[
Category(id=3),
Category(id=4),
Category(id=5, children=[Category(id=6), Category(id=7)]),
],
),
],
)
session.add(root)
session.flush()
session.expire_all()
cat = session.query(Category).filter(Category.id == 0).one()
print(f"Category: {cat!r}")
print(f" deep_children_count: {cat.deep_children_count}")
print(f" children: {[c.id for c in cat.children]}")
# Check each child's deep_children too
for c in cat.children:
print(f" Child {c.id} => deep_children = {c.deep_children}")
session.close()
< /code>
Полученная ошибка: < /p>
sqlalchemy.exc.CompileError: All selectables passed to CompoundSelect must have identical numbers of columns; select #1 has 1 columns, select #2 has 3
Подробнее здесь: https://stackoverflow.com/questions/794 ... sqlalchemy
Рекурсивное свойство, определяемое как Property_column в sqlalchemy ⇐ Python
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Панды: добавьте несколько столбцов в DataFrame Column Column Multiindex
Anonymous » » в форуме Python - 0 Ответы
- 10 Просмотры
-
Последнее сообщение Anonymous
-