SQLAlchemy模块没有找到,尽管已经安装了Pipenv



我正在学习使用FastAPI, psycopg2和SQLAlchemy与python,它一直工作良好。现在,由于某种原因,每当我运行我的web应用程序时,都找不到SQLAlchemy模块。

我在Pipenv中运行它,python 3.11.1和SQLAlchemy 1.4.45,并且运行pip freeze显示SQLAlchemy已经安装,并且我的源代码肯定是我的Pipenv环境,与我运行fastAPI服务器的环境相同。

我已经尝试用Pipenv卸载和重新安装SQLAlchemy,当我在交互模式下运行python时,它是预期的python版本,我能够导入SQLAlchemy并检查SQLAlchemy。版本.

任何想法为什么它说它不能导入当我运行FastAPI?

从我的models.py模块导入到main.py中的代码:

from sqlalchemy import Column, Integer, String, Boolean
from app.database import Base

class Post(Base):
__tablename__ = "posts"
id = Column(Integer, primary_key=True, nullable=False)
title = Column(String, nullable=False)
content = Column(String, nullable=False)
published = Column(Boolean, default=True)
# timestamp = Column(TIMESTAMP, default=now())
<标题>main.py:
from fastapi import FastAPI, Response, status, HTTPException, Depends
from pydantic import BaseModel
import psycopg2
from psycopg2.extras import RealDictCursor
import time
from app import models
from sqlalchemy.orm import Session
from app.database import engine, SessionLocal
models.Base.metadata.create_all(bind=engine)
# FastAPI initialisation
app = FastAPI()

# function to initialise SQlAlchemy DB session dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()

# psycopg2 DB connection initialisation
while True:
try:
conn = psycopg2.connect(host="localhost", dbname="fastapi", user="postgres",
password="*********", cursor_factory=RealDictCursor)
cursor = conn.cursor()
print('Database connection successful.')
break
except Exception as error:
print("Connecting to database failed.")
print("Error: ", error)
print("Reconnecting after 2 seconds")
time.sleep(2)

# this class defines the expected fields for the posts extending the BaseModel class
# from Pydantic for input validation and exception handling ==> a "schema"
class Post(BaseModel):
title: str
content: str
published: bool = True

# this list holds posts, with 2 hard coded for testing purposes
my_posts = [{"title": "title of post 1", "content": "content of post 1", "id": 1},
{"title": "title of post 2", "content": "content of post 2", "id": 2}]

# this small function simply finds posts by id by iterating though the my_posts list
def find_post(find_id):
for post in my_posts:
if post["id"] == find_id:
return post

def find_index(find_id):
try:
index = my_posts.index(find_post(find_id))
except:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Post of id: {find_id} not found.")
return index

# these decorated functions act as routes for FastAPI.
# the decorator is used to define the HTTP request verb (e.g. get, post, delete, patch, put),
# as well as API endpoints within the app (e.g. "/" is root),
# and default HTTP status codes.
@app.get("/")
async def root():
return {"message": "Hello World"}

# "CRUD" (Create, Read, Update, Delete) says to use same endpoint
# but with different HTTP request verbs for the different request types.
# (e.g. using "/posts" for all four CRUD operations, but using POST, GET, PUT/PATCH, DELETE respectively.)
@app.get("/posts")
def get_data():
cursor.execute("SELECT * FROM posts")
posts = cursor.fetchall()
print(posts)
return {"data": posts}

@app.post("/posts", status_code=status.HTTP_201_CREATED)
def create_posts(post: Post):
cursor.execute("INSERT INTO posts (title, content, published) VALUES (%s, %s, %s) RETURNING *",
(post.title, post.content, post.published))
new_post = cursor.fetchone()
conn.commit()
return {"created post": new_post}

@app.delete("/posts/{id}")
def delete_post(id: int):
cursor.execute("DELETE FROM posts * WHERE id = %s RETURNING *", str(id))
deleted_post = cursor.fetchone()
conn.commit()
if deleted_post is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"post with id: {id} not found.")
else:
print("deleted post:", deleted_post)
return Response(status_code=status.HTTP_204_NO_CONTENT)

@app.get("/posts/{id}")
def get_post(id: int):
cursor.execute("SELECT * FROM posts WHERE id = %s", str(id))
post = cursor.fetchone()
if post is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"post with id: {id} was not found.")
return {"post_detail": post}

@app.put("/posts/{id}")
def update_post(id: int, put: Post):
cursor.execute("UPDATE posts SET title = %s, content = %s, published= %s WHERE id = %s RETURNING *",
(put.title, put.content, put.published, str(id)))
updated_post = cursor.fetchone()
if updated_post is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"post with id: {id} was not found.")
return {"updated_post_detail": updated_post}

@app.get("/sqlalchemy")
def test_posts(db: Session = Depends(get_db)):
return {"status": "success"}
<标题>错误日志:
louisgreenhalgh@MacBook-Pro  ~/PycharmProjects/FASTAPI  uvicorn app.main:app --reload                                                                                                ✔  FASTAPI-3Pf2tu2f
INFO:     Will watch for changes in these directories: ['/Users/louisgreenhalgh/PycharmProjects/FASTAPI']
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [32662] using WatchFiles
Process SpawnProcess-1:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/multiprocessing/process.py", line 314, in _bootstrap
self.run()
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/uvicorn/_subprocess.py", line 76, in subprocess_started
target(sockets=sockets)
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/uvicorn/server.py", line 60, in run
return asyncio.run(self.serve(sockets=sockets))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/runners.py", line 190, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "uvloop/loop.pyx", line 1517, in uvloop.loop.Loop.run_until_complete
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/uvicorn/server.py", line 67, in serve
config.load()
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/uvicorn/config.py", line 477, in load
self.loaded_app = import_from_string(self.app)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/uvicorn/importer.py", line 24, in import_from_string
raise exc from None
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/uvicorn/importer.py", line 21, in import_from_string
module = importlib.import_module(module_str)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1206, in _gcd_import
File "<frozen importlib._bootstrap>", line 1178, in _find_and_load
File "<frozen importlib._bootstrap>", line 1149, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 940, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "/Users/louisgreenhalgh/PycharmProjects/FASTAPI/app/main.py", line 6, in <module>
from app import models
File "/Users/louisgreenhalgh/PycharmProjects/FASTAPI/app/models.py", line 1, in <module>
from sqlalchemy import Column, Integer, String, Boolean
ModuleNotFoundError: No module named 'sqlalchemy'

Pipenv图输出:

fastapi==0.88.0
- pydantic [required: >=1.6.2,<2.0.0,!=1.8.1,!=1.8,!=1.7.3,!=1.7.2,!=1.7.1,!=1.7, installed: 1.10.4]
- typing-extensions [required: >=4.2.0, installed: 4.4.0]
- starlette [required: ==0.22.0, installed: 0.22.0]
- anyio [required: >=3.4.0,<5, installed: 3.6.2]
- idna [required: >=2.8, installed: 3.4]
- sniffio [required: >=1.1, installed: 1.3.0]
greenlet==2.0.1
psycopg2-binary==2.9.5
SQLAlchemy==1.4.45

最有可能的问题是uvicorn可执行文件不存在于相同的python (v)环境中。当python进程启动时,它会查看二进制文件的位置(在本例中是uvicorn),确定python的基本位置(与二进制文件所在的文件夹相同,或者上面的一个文件夹),并最终根据该基本位置添加适当的site_packages位置。

所以在您的情况下,尝试pip(env)将uvicorn安装到相同的虚拟环境

最新更新