К основному содержанию
правило

pony — правило Cursor для Pony ORM: что делает и как установить

Правило для Cursor задаёт стиль работы с Pony ORM: сессии, запросы, типизация, разделение слоёв. Пригодится, если проект на Python с Pony ORM.

Установить в Cursor · Вручную: положить файлы Все способы и платформы ↓
.cursor/rules/pony.mdc
Открыть на GitHub

Что делает pony

Файл pony.mdc подключается к Cursor и подсказывает агенту, как писать код на Pony ORM. Внутри шесть разделов: работа через db_session, генераторные запросы вместо ручного SQL, разделение моделей и сервисов, типизация сущностей, доверие встроенному кэшу и IdentityMap, синхронизация схемы с моделями. Каждое правило идёт парой примеров — как не надо и как надо.

Правило срабатывает на файлах **/*.py, так что в Python-проекте оно подхватится само. Ничего дополнительно ставить не нужно: это обычный mdc-файл в .cursor/rules/. Правда, польза будет только там, где уже используется Pony ORM — на SQLAlchemy или Django ORM советы про db_session и select(p for p in Product) просто не к месту.

Автор советует держать сущности в models.py, а операции с данными — в repositories.py или services.py. Это влияет на структуру проекта, поэтому решать стоит до того, как кодовая база разрастётся.

Какие задачи решает

  • забыть закоммитить транзакцию и получить утечку соединения
  • вытащить все записи в Python и фильтровать их в цикле
  • смешать модели, настройку базы и бизнес-логику в одном файле
  • потерять типы у атрибутов сущностей и параметров функций
  • написать свой кэш поверх IdentityMap и ловить устаревшие данные

Примеры запросов агенту

  • Перепиши эту функцию так, чтобы вся работа с базой шла внутри db_session.
  • Замени фильтрацию в Python на запрос через select по Product.
  • Разнеси этот файл на models.py и services.py и добавь типы.

Как установить pony

Вручную: положить файлы

.cursor/rules/pony.mdc

Во frontmatter: description, globs, alwaysApply

По шагам, с командами для каждой платформы: Cursor rules: файлы .mdc, четыре режима и замена .cursorrules

Вопросы о pony

Как установить правило pony в Cursor?

Создайте файл .cursor/rules/pony.mdc и вставьте в него содержимое правила.

Что делает правило pony?

Задаёт агенту Cursor соглашения по Pony ORM: транзакции через db_session, запросы генераторами, типизация, разделение слоёв доступа к данным.

На какие файлы распространяется правило?

На все Python-файлы по маске **/*.py.

Исходный текст

pony.mdc · CC0-1.0
---
description: Definitive guidelines for writing efficient, maintainable, and secure Python applications using Pony ORM.
globs: **/*.py
---
# pony Best Practices

Pony ORM simplifies database interactions with Pythonic syntax and powerful optimizations. Adhere to these rules for robust, high-performance applications.

## 1. Always Use `db_session` for Transaction Management

The `db_session` context manager is non-negotiable. It ensures proper transaction handling, automatic commits, and rollbacks, preventing resource leaks and data inconsistencies.

❌ BAD: Direct database operations without a session.
```python
from pony.orm import *
from decimal import Decimal

db = Database('sqlite', ':memory:')

class Product(db.Entity):
    name = Required(str)
    price = Required(Decimal)

db.generate_mapping(create_tables=True)

# This will fail or lead to unexpected behavior in production
p = Product(name='Laptop', price=Decimal('1200.00'))
db.commit() # Manual commit is error-prone and easily forgotten
```

✅ GOOD: Encapsulate all database work within `db_session`.
```python
from pony.orm import *
from decimal import Decimal

db = Database('sqlite', ':memory:')

class Product(db.Entity):
    name = Required(str)
    price = Required(Decimal)

db.generate_mapping(create_tables=True)

@db_session
def create_product(name: str, price: Decimal) -> Product:
    p = Product(name=name, price=price)
    return p # Auto-committed on exit if no exception

with db_session:
    laptop = create_product('Laptop', Decimal('1200.00'))
    print(f"Created product: {laptop.name}")
```

## 2. Leverage Pythonic Query Syntax for Optimization

Pony translates generator expressions and lambdas into optimized SQL, automatically handling N+1 problems and complex joins. Avoid manual SQL unless absolutely necessary.

❌ BAD: Manual filtering or inefficient data access.
```python
@db_session
def get_expensive_products_bad():
    all_products = list(select(p for p in Product)) # Fetches all products
    expensive_products = [p for p in all_products if p.price > Decimal('1000')] # Filters in Python
    return expensive_products
```

✅ GOOD: Let Pony generate optimized SQL.
```python
@db_session
def get_expensive_products_good() -> list[Product]:
    # Pony translates this directly to SQL: SELECT ... WHERE price > 1000
    return select(p for p in Product if p.price > Decimal('1000'))[:] # Use [:] to fetch all results
```

## 3. Separate Data Access from Business Logic

Maintain a clean architecture by defining entities in a dedicated `models.py` and encapsulating data operations in a `repositories.py` or `services.py` module.

❌ BAD: Mixing entity definitions, database setup, and business logic in one file.
```python
# app.py
from pony.orm import *
db = Database('sqlite', 'app.sqlite')
class User(db.Entity):
    name = Required(str)
    email = Required(str, unique=True)
db.generate_mapping(create_tables=True)

@db_session
def create_user_and_send_email(name, email):
    user = User(name=name, email=email)
    # ... send email logic here ...
```

✅ GOOD: Clear separation of concerns.
```python
# models.py
from pony.orm import *
db = Database() # Bind later

class User(db.Entity):
    id = PrimaryKey(int, auto=True)
    name = Required(str)
    email = Required(str, unique=True)

# database.py
from pony.orm import Database
from .models import db # Import db instance

def setup_database(provider: str, filename: str):
    db.bind(provider=provider, filename=filename, create_db=True)
    db.generate_mapping(create_tables=True)

# services.py
from pony.orm import db_session
from .models import User
from typing import List

@db_session
def create_user(name: str, email: str) -> User:
    user = User(name=name, email=email)
    return user

@db_session
def get_all_users() -> List[User]:
    return list(select(u for u in User))

# main.py (or app.py)
from .database import setup_database
from .services import create_user, get_all_users

if __name__ == '__main__':
    setup_database('sqlite', 'my_app.sqlite')
    
    create_user('Alice', '[email protected]')
    create_user('Bob', '[email protected]')
    
    for user in get_all_users():
        print(f"User: {user.name}, Email: {user.email}")
```

## 4. Apply Static Typing to Entities and Queries

Use type hints (`typing` module) for entity attributes and function signatures. This improves readability, enables IDE auto-completion, and catches errors early.

❌ BAD: Untyped entity attributes and function parameters.
```python
class Order(db.Entity):
    amount = Required(float) # float is imprecise for currency
    customer = Required('Customer')

@db_session
def get_total_orders(customer_id): # No type hints
    customer = Customer[customer_id]
    return sum(o.amount for o in customer.orders)
```

✅ GOOD: Explicit type hints for clarity and correctness.
```python
from decimal import Decimal
from typing import List

class Customer(db.Entity):
    id = PrimaryKey(int, auto=True)
    name = Required(str)
    orders: List['Order'] # Forward reference for type hinting

class Order(db.Entity):
    id = PrimaryKey(int, auto=True)
    amount = Required(Decimal) # Use Decimal for currency
    customer = Required(Customer)

@db_session
def get_customer_total_orders(customer_id: int) -> Decimal:
    customer: Customer = Customer[customer_id]
    # Pony handles aggregation efficiently
    total_amount: Decimal = sum(o.amount for o in customer.orders)
    return total_amount
```

## 5. Utilize Pony's Automatic Caching and IdentityMap

Pony automatically caches entities and query results within a `db_session`. Avoid manual caching layers for simple entity lookups to prevent stale data.

❌ BAD: Implementing a custom cache for entities within a session.
```python
my_entity_cache = {} # Don't do this; it's redundant and error-prone with Pony

@db_session
def get_user_cached(user_id: int) -> User:
    if user_id not in my_entity_cache:
        user = User[user_id]
        my_entity_cache[user_id] = user
    return my_entity_cache[user_id]
```

✅ GOOD: Trust Pony's IdentityMap and session-level caching.
```python
@db_session
def get_user_pony_cached(user_id: int) -> User:
    # Pony's IdentityMap ensures that User[user_id] returns the same object
    # within the session if it has already been fetched.
    user1 = User[user_id]
    user2 = User[user_id]
    assert user1 is user2 # This assertion is True within the same db_session
    return user1
```

## 6. Manage Schema with the Online Editor or Versioned Scripts

Keep your Pony model definitions in sync with the database schema. For complex projects, use version-controlled migration scripts. For rapid prototyping, Pony's online editor is excellent.

❌ BAD: Manually altering database tables without updating Pony models, or vice-versa.
```python
# models.py
class Product(db.Entity):
    name = Required(str)
    # Forgot to add 'description' here, but added it to DB manually, leading to mismatches.
```

✅ GOOD: Use `db.generate_mapping(create_tables=True)` for initial setup and Pony's editor or custom migration scripts for changes.
```python
# Initial setup
db.generate_mapping(create_tables=True)

# For schema changes, either use Pony's online editor to generate SQL
# or write explicit migration scripts (e.g., using Alembic or custom logic)
# to apply changes and then update your Pony entity definitions.
```

© sanjeed5 · CC0-1.0 · sanjeed5/awesome-cursor-rules-mdc

Похожие правила IDE

Все правила IDE по теме «Данные и базы» →
django-expert vintasoftware Подсказывает агенту, как писать модели, вьюхи, сериализаторы DRF и оптимизировать запросы ORM по практикам Django. CX Codex +1 5 700установок SQLAlchemy ORM Expert Customer Support Tech Enablement Team Скилл по SQLAlchemy 2.0+ для поддержки клиентов: модели тикетов, сессии, async-запросы и PostgreSQL. Пригодится, когда пишете бэкенд на FastAPI. CX Codex +1 470установок odoo-development Mindrally Скилл для ИИ-агента, который подсказывает, как писать модули Odoo: модели на Python ORM, XML-представления, права доступа. CX Codex +1 2 300установок odoo-19 unclecatvn Скилл с 18 справочниками по Odoo 19: ORM, декораторы, OWL, QWeb-отчёты, миграции. Пригодится, когда агент пишет или правит Python и XML код модуля. CX Codex +1 2 000установок django-python Mindrally Скилл задаёт агенту стиль работы с Django: MVT, ORM вместо сырого SQL, class-based views и разбор ошибок на уровне представлений. CX Codex +1 933установок django-patterns affaan-m Помогает проектировать архитектуру Django и DRF: настраивать раздельные конфигурации, писать кастомные QuerySet и организовывать структуру приложений. CX Codex +1 5 200установок

Из того же набора79

pytest Правило задаёт команде единый стиль тестов на pytest: структуру проекта, фикстуры, параметризацию и моки. Пригодится, когда тесты пишут несколько человек. ★ 3 579звёзд репо pyramid Правило для Cursor с набором практик по Python-фреймворку Pyramid: структура проекта, конфигурация, транзакции и предикаты представлений. ★ 3 579звёзд репо pygame Правило для Cursor задаёт каркас Pygame-проекта: один UIManager, фиксированный шаг времени, вёрстка на якорях и темы в JSON. ★ 3 579звёзд репо prisma Правило для Cursor, которое задаёт агенту порядок работы с Prisma ORM: один клиент на приложение, выборки без лишних полей, аккуратные миграции. ★ 3 579звёзд репо playwright Правило задаёт Cursor стандарты написания end-to-end тестов на Playwright: официальный раннер, устойчивые локаторы, отказ от ручных задержек. ★ 3 579звёзд репо phoenix Правило для Cursor задаёт, как писать Phoenix-приложения на Elixir: контексты, форматирование, тесты. Пригодится, если агент уже правит ваш код. ★ 3 579звёзд репо pandas Правило для Cursor задаёт стиль работы с pandas: векторизация вместо циклов, явные .loc и .iloc, экономные типы данных. Пригодится, если агент часто пишет медленный код. ★ 3 579звёзд репо nuxt Правило для Cursor задаёт агенту стиль кода в Nuxt-проекте: структура каталогов, Composition API, Pinia, useFetch. Пригодится, если агент уже начал плодить миксины и onMounted вместо SSR-фетча. ★ 3 579звёзд репо

Спонсоры проекта

Компании, которые помогают держать аналитику открытой