diff --git a/docs/databases/development/python/coding/repository.md b/docs/databases/development/python/coding/repository.md index 2fbb84e..e612a1f 100644 --- a/docs/databases/development/python/coding/repository.md +++ b/docs/databases/development/python/coding/repository.md @@ -597,7 +597,7 @@ def test_create_user_error(mock_conn): ) def test_get_all_users_success(mock_conn): - now = datetime.utcnow() + now = datetime.now() expected = [{ "id": 1, "user_name": "john", @@ -634,7 +634,7 @@ def test_get_all_users_error(mock_conn): def test_get_user_by_id_success(mock_conn): - now = datetime.utcnow() + now = datetime.now() expected = { "user_name": "john", "first_name": "John", @@ -687,7 +687,7 @@ def test_get_user_by_username_not_found(mock_conn): def test_update_user_success(mock_conn): - now = datetime.utcnow() + now = datetime.now() earlier = now - timedelta(hours=1) dto = { @@ -754,7 +754,7 @@ def test_delete_user_not_found(mock_conn): После этого выполните команду ```bash -pytest-v +pytest -v ``` Если вы все сделали правильно, все тесты пройдены. @@ -1212,7 +1212,7 @@ def like_post(post_id: int, user_id: int) -> None: try: with pool.connection() as conn: with conn.cursor() as cur: - cur.execute(query, (post_id, user_id, post_id)) + cur.execute(query, (post_id, user_id)) if cur.rowcount == 0: raise ValueError("Post not found") except UniqueViolation as err: @@ -1237,7 +1237,7 @@ def dislike_post(post_id: int, user_id: int) -> None: with pool.connection() as conn: with conn.cursor() as cur: - cur.execute(query, (post_id, user_id, post_id)) + cur.execute(query, (post_id, user_id)) if cur.rowcount == 0: raise ValueError("Post not found") ``` @@ -1283,7 +1283,7 @@ def test_create_post_success(mock_conn): expected = { "id": 1, "text": dto["text"], - "created_at": datetime.utcnow(), + "created_at": datetime.now(), "reply_to_id": None, } @@ -1336,7 +1336,7 @@ def test_create_post_success(mock_conn): expected = { "id": 1, "text": dto["text"], - "created_at": datetime.utcnow(), + "created_at": datetime.now(), "reply_to_id": None, } @@ -1502,7 +1502,7 @@ def test_get_all_posts_error(mock_conn): def test_get_post_by_id_success(mock_conn): user_id = 1 post_id = 1 - now = datetime.utcnow() + now = datetime.now() row = { "post_id": post_id, @@ -1668,7 +1668,7 @@ def test_like_post_success(mock_conn): assert "insert into likes (post_id, user_id)" in normalized_sql params = mock_cursor.execute.call_args[0][1] - assert params == (post_id, user_id, post_id) + assert params == (post_id, user_id) def test_like_post_error(mock_conn): @@ -1687,7 +1687,7 @@ def test_like_post_error(mock_conn): assert "insert into likes (post_id, user_id)" in normalized_sql params = mock_cursor.execute.call_args[0][1] - assert params == (post_id, user_id, post_id) + assert params == (post_id, user_id) def test_like_post_already_liked(mock_conn): @@ -1718,7 +1718,7 @@ def test_dislike_post_success(mock_conn): assert "delete from likes where post_id = %s and user_id = %s" in normalized_sql params = mock_cursor.execute.call_args[0][1] - assert params == (post_id, user_id, post_id) + assert params == (post_id, user_id) def test_dislike_post_error(mock_conn): @@ -1737,7 +1737,7 @@ def test_dislike_post_error(mock_conn): assert "delete from likes where post_id = %s and user_id = %s" in normalized_sql params = mock_cursor.execute.call_args[0][1] - assert params == (post_id, user_id, post_id) + assert params == (post_id, user_id) def test_dislike_post_not_found(mock_conn): @@ -1756,7 +1756,7 @@ def test_dislike_post_not_found(mock_conn): assert "delete from likes where post_id = %s and user_id = %s" in normalized_sql params = mock_cursor.execute.call_args[0][1] - assert params == (post_id, user_id, post_id) + assert params == (post_id, user_id) ``` ::: diff --git a/docs/databases/development/python/design/database-connection.md b/docs/databases/development/python/design/database-connection.md index f08612d..0074461 100644 --- a/docs/databases/development/python/design/database-connection.md +++ b/docs/databases/development/python/design/database-connection.md @@ -20,6 +20,28 @@ Благодаря этому мы сможем использовать **всю мощь PostgreSQL прямо из кода на Python** — просто, эффективно и без необходимости использовать ORM. +## Установка библиотеки + +Прежде чем приступить к изучению возможностей адаптера `psycopg`, необходимо установить соответствующую библиотеку для Python. + +Как указано в официальной документации, сначала убедитесь, что версия менеджера пакетов `pip` не ниже 20.3: + +```bash +pip install --upgrade pip +``` + +Затем установите модуль `psycopg[binary]`, который не требует наличия системных зависимостей: + +```bash +pip install "psycopg[binary]" +``` + +Установите `psycopg_pool`: + +```bash +pip install psycopg_pool +``` + ## Основы API библиотеки `psycopg` Библиотека `psycopg` предоставляет несколько ключевых интерфейсов для работы с PostgreSQL в соответствии со стандартом [**Python DB API 2.0**](https://peps.python.org/pep-0249/). @@ -61,30 +83,25 @@ conn.close() - По умолчанию `psycopg` использует неавтоматические транзакции: нужно вызывать `conn.commit()` или `conn.rollback()`. Параметры подключения: - -```python -psycopg.connect( - host="localhost", - port=5432, - user="postgres", - password="secret", - dbname="mydb", - connect_timeout=10, - application_name="myapp" -) - -``` +- **host** — адрес сервера PostgreSQL (Например, `localhost` для локального подключения); +- **port** — порт, на котором работает PostgreSQL (По умолчанию - 5432); +- **user** — имя пользователя PostgreSQL; +- **password** — пароль пользователя; +- **dbname** — имя базы данных, к которой осуществляется подключение; +- **connect_timeout** (необязательный параметр) — таймаут в секундах при установке соединения. Также можно использовать DSN-строку: ```python -psycopg.connect("postgresql://postgres:secret@localhost:5432/mydb") +psycopg.connect(conninfo="postgresql://postgres:secret@localhost:5432/mydb") ``` ### 2. Пул подключений (рекомендуемый способ) Объект `ConnectionPool` из модуля `psycopg_pool` управляет множеством соединений с базой данных. Это более производительный и устойчивый способ подключения в реальных приложениях. +pip install psycopg_pool + #### Пример: ```python @@ -277,14 +294,12 @@ pool = ConnectionPool( ```python import os - from dotenv import load_dotenv from fastapi import FastAPI, Response, status +from config.db import pool load_dotenv() -from config.db import pool - app = FastAPI() port = int(os.getenv("PORT", 3000))