4 fastAPI与postgres数据库

在 FastAPI 中与 PostGIS(PostgreSQL 的地理空间扩展)数据库交互时,我们可以使用 psycopg2(PostgreSQL 的 Python 连接库)和 SQLAlchemy 来进行操作。如果需要进行地理空间查询或存储地理空间数据,GeoAlchemy2 是一个常用的库,它扩展了 SQLAlchemy,使其能够处理地理空间数据。下面是如何在 FastAPI 中与 PostGIS 数据库集成的详细步骤。


1. 安装必要的依赖

首先,安装必要的依赖库,包括 FastAPI、SQLAlchemy、GeoAlchemy2 和 psycopg2。


pip install fastapi uvicorn sqlalchemy geoalchemy2 psycopg2
  • psycopg2 用于连接 PostgreSQL 数据库。
  • geoalchemy2 用于在 SQLAlchemy 中支持地理空间数据类型(如 POINTPOLYGON 等)。
  • SQLAlchemy 用于 ORM 操作。

2. 数据库配置

在这个示例中,我们将使用 SQLAlchemy 来连接 PostGIS 数据库,并通过 GeoAlchemy2 来操作地理空间数据。

配置数据库连接和模型

首先,创建一个连接到 PostGIS 数据库的 SQLAlchemy 引擎,并定义一个数据模型来存储地理空间数据。

from fastapi import FastAPI, Depends
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from geoalchemy2 import Geometry
from sqlalchemy.future import select

# 配置数据库连接 URL(PostGIS 数据库)
DATABASE_URL = "postgresql://user:password@localhost/dbname"

# 创建 SQLAlchemy 引擎
engine = create_engine(DATABASE_URL, echo=True)

# 创建数据库会话
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# 创建模型基础类
Base = declarative_base()

# 定义数据模型
class Location(Base):
    __tablename__ = "locations"
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, index=True)
    location = Column(Geometry(geometry_type='POINT', srid=4326))

# 创建数据库表
Base.metadata.create_all(bind=engine)

在这个模型中,我们定义了一个名为 Location 的表,该表包含:

  • id: 主键。
  • name: 名称字段,用于存储位置名称。
  • location: 地理空间字段,使用 GeoAlchemy2Geometry 类型,这里指定为 POINT 类型,表示经纬度。

3. FastAPI 路由:创建和查询地理空间数据

接下来,我们将创建一些路由来插入和查询地理空间数据。

插入地理空间数据(例如经纬度)
from fastapi import FastAPI, HTTPException
from sqlalchemy.orm import Session
from pydantic import BaseModel
from geoalchemy2.shape import to_shape
from shapely.geometry import Point

app = FastAPI()

# Pydantic 模型,用于验证请求体数据
class LocationCreate(BaseModel):
    name: str
    latitude: float
    longitude: float

@app.post("/locations/")
def create_location(location: LocationCreate, db: Session = Depends(get_db)):
    # 创建一个 Point 对象(经纬度)
    point = Point(location.longitude, location.latitude)
    
    # 将 Point 转换为 PostGIS 所需的格式
    geo_point = to_shape(point)

    # 插入数据到数据库
    db_location = Location(name=location.name, location=geo_point)
    db.add(db_location)
    db.commit()
    db.refresh(db_location)
    return db_location
  • LocationCreate 是一个 Pydantic 模型,用于接收请求体中的数据。
  • 我们使用 Shapely 库来创建一个 Point 对象,表示地理位置。
  • 使用 GeoAlchemy2to_shape 函数将 Point 转换为数据库可以存储的格式。
查询地理空间数据(根据经纬度查询)
from sqlalchemy.orm import Session
from sqlalchemy import func
from shapely.geometry import Point
from geoalchemy2.functions import ST_Distance

@app.get("/locations/nearby/")
def get_nearby_locations(latitude: float, longitude: float, radius: float, db: Session = Depends(get_db)):
    # 创建查询点
    point = Point(longitude, latitude)
    
    # 使用 PostGIS 的地理空间函数查询附近的地点
    query = db.query(Location).filter(
        ST_Distance(Location.location, point) < radius  # 半径范围内查询
    )
    
    locations = query.all()
    return locations
  • ST_Distance 是一个 PostGIS 提供的函数,用于计算地理空间数据之间的距离。
  • get_nearby_locations 路由根据经纬度和半径查询附近的地点。
获取数据库会话
# 获取数据库会话
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

4. 启动应用

运行 FastAPI 应用:


uvicorn app:app --reload

5. 测试 API

请求:插入一个新的位置

使用以下 POST 请求将一个新位置插入数据库:


POST /locations/

请求体:

{
  "name": "Eiffel Tower",
  "latitude": 48.8584,
  "longitude": 2.2945
}
请求:查询附近的位置

例如,查询距离某个点 1000 米以内的所有位置:


GET /locations/nearby/?latitude=48.8584&longitude=2.2945&radius=1000

6. PostGIS 查询和操作

在 FastAPI 中,我们通过 SQLAlchemy 和 GeoAlchemy2 实现了 PostGIS 数据库的基本操作。你可以利用 PostGIS 提供的丰富地理空间查询和操作功能,例如:

  • ST_Within: 判断一个地理对象是否在另一个对象内。
  • ST_Intersects: 判断两个地理对象是否相交。
  • ST_Contains: 判断一个地理对象是否包含另一个对象。
  • ST_Area: 计算多边形的面积。
  • ST_Length: 计算线的长度。

这些查询都可以通过 SQLAlchemy 和 GeoAlchemy2 在 FastAPI 中轻松实现。

FastAPI 与 PostGIS 数据库的集成主要通过以下几个步骤完成:

  • 使用 psycopg2 连接到 PostGIS 数据库。
  • 使用 GeoAlchemy2 扩展 SQLAlchemy 以支持地理空间数据类型和查询。
  • 通过 FastAPI 路由处理地理空间数据的插入和查询。

这种集成方式让 FastAPI 成为构建地理空间应用(如地图应用、位置服务等)的理想选择。

4 fastAPI与postgres数据库_第1张图片

你可能感兴趣的:(python,FastAPI,fastapi,数据库)