FastAPI对接已有Oracle表:替换create_all代码方案咨询
问题:对接已存在Oracle表时,如何处理
Base.metadata.create_all语句? 现有Oracle数据库中已存在table1和table2两张表,我希望编写一个FastAPI接口,实现输入参数cn后返回对应结果。现有代码如下:
from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker, Session import cx_Oracle from fastapi import Depends, FastAPI from sqlalchemy import Column, Integer, String cx_Oracle.init_oracle_client(lib_dir=r"E:\instantclient-basic-windows.x64-12.1.0.2.0\instantclient_12_1") my_database_connection = "oracle+cx_oracle://super:admin@192.168.91.47:1521/db" engine = create_engine(my_database_connection) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) Base = declarative_base() class table1(Base): __tablename__ = "table1" CN = Column(String(length=256)) NAME = Column(String(length=40)) EMAIL = Column(String(length=20)) Base.metadata.create_all(bind=engine) # Base.metadata. app = FastAPI() def get_db(): db = SessionLocal() try: yield db finally: db.close() @app.get("/table_api/") def read_users(db:Session = Depends(get_db)): cninformation = db.query(table1).all() return cninformation
由于table1已存在,上述代码中的Base.metadata.create_all(bind=engine)语句会尝试创建表,属于冗余写法。若要对接已存在的表,该行代码应如何处理?
解答
直接删除Base.metadata.create_all(bind=engine)这行代码即可,不需要替换成其他代码。
原因:
Base.metadata.create_all()的作用是扫描所有继承自Base的模型类,在数据库中创建那些还不存在的表。既然你的table1已经存在,这行代码完全没有存在的必要,保留它反而可能在模型字段和数据库表结构不一致时引发不必要的问题。
额外优化建议:
- 给模型添加主键:SQLAlchemy ORM要求每个模型必须定义主键字段,否则执行查询操作时会报错。修改table1模型,给CN字段加上主键约束:
class table1(Base): __tablename__ = "table1" CN = Column(String(length=256), primary_key=True) # 添加主键约束 NAME = Column(String(length=40)) EMAIL = Column(String(length=20))
- 修改接口支持cn参数:你的需求是输入cn参数返回对应结果,当前接口没有接收参数,需要调整接口定义:
@app.get("/table_api/") def read_users(cn: str, db: Session = Depends(get_db)): # 根据cn参数过滤查询,返回匹配的第一条数据 cn_information = db.query(table1).filter(table1.CN == cn).first() return cn_information
内容的提问来源于stack exchange,提问作者Andrew8460958
相关产品推荐
相关产品推荐

