[英]FastAPI testing No ORM Databases
I am a None ORM user, I prefer to use plain text queries, I took that course on free code camp on FastAPI but almost the whole course revolves around ORMs so I struggle to implement a number of concepts found in that course.我是无 ORM 用户,我更喜欢使用纯文本查询,我在 FastAPI 上的免费代码营上学习了该课程,但几乎整个课程都围绕 ORM,所以我很难实现该课程中的一些概念。
My main struggle is when I write tests for my endpoints I need to use a test database rather than my development database, I am using testing.postgres to create the testing database and this is the code I am using:我的主要困难是当我为端点编写测试时,我需要使用测试数据库而不是我的开发数据库,我正在使用testing.postgres创建测试数据库,这是我正在使用的代码:
client = TestClient(app)
class TestUser:
def setup_method(self, method):
self.postgres = testing.postgresql.Postgresql(cache_initialized_db=True)
self.db = psycopg2.connect(**self.postgres.dsn())
def teardown_method(self, method):
self.db.close()
def test_get_users(self):
res = client.get("/users")
assert res.status_code == 200
assert res.headers["content-type"] == "application/json"
my question is how to make my tests and cruds send queries to the test database, not the development database.我的问题是如何让我的测试和 cruds 将查询发送到测试数据库,而不是开发数据库。
where is the link that I should add here?我应该在这里添加的链接在哪里?
Edit: this is the code I use for connection with database, I am not using a dependency for it:编辑:这是我用于连接数据库的代码,我没有使用它的依赖项:
while True:
try:
conn = psycopg2.connect(
database=settings.database,
user=settings.user,
port=settings.port,
password=settings.password,
cursor_factory=RealDictCursor,
)
cr = conn.cursor()
console.print(
"[green bold]SUCCESS[/]: Connection To Database Established successfuly"
)
break
except psycopg2.OperationalError:
console.print(
"[red bold]FAILED[/]: Connection To Database Failed , Trying Again"
)
time.sleep(2)
Edit2: this is the settings segment: Edit2:这是设置部分:
load_dotenv()
class Settings(BaseSettings):
database: str
user: str
port: int
password: str
expiray: int
algorithm: str
secret_key: str
settings = Settings()
If you wanna use the test database rather than the development database you should create the testing database and let the backend application be able to find the testing database and use it.如果您想使用测试数据库而不是开发数据库,您应该创建测试数据库并让后端应用程序能够找到并使用测试数据库。
Kareem, I suggest you create your Settings
instance from one or another .env
file, based on an ENVIRONMENT
variable: Kareem,我建议您根据ENVIRONMENT
变量从一个或另一个.env
文件创建您的Settings
实例:
import os
import sys
import pydantic
class Settings(pydantic.BaseSettings):
database: str
user: str
port: int
password: str
expiray: int
algorithm: str
secret_key: str
try:
ENVIRONMENT = os.environ['ENVIRONMENT']
except KeyError:
print('make sure to set an "ENVIRONMENT" env var')
sys.exit()
settings = Settings(_env_file=f'{ENVIRONMENT}.env', _env_file_encoding='utf-8')
This way, if you want to work with the testing database, you can do $ export ENVIRONMENT=test
and it will load the settings from a file called test.env
.这样,如果您想使用测试数据库,您可以执行$ export ENVIRONMENT=test
,它将从名为test.env
的文件中加载设置。
Does that make sense?那有意义吗? Here are the docs for pydantic
's dotenv
support for BaseSettings
subclasses. 这是pydantic 对pydantic
子类的dotenv
支持的BaseSettings
。
As an aside, since you're interested in doing as much as you can without the use of an ORM and perhaps other dependencies, you really don't need pydantic
for your purposes: You could simply change the above to something like:顺便说一句,由于您有兴趣在不使用 ORM 和其他依赖项的情况下尽可能多地做事,因此您真的不需要pydantic
来实现您的目的:您可以简单地将上面的内容更改为:
import os
import sys
import types
import dotenv
try:
ENVIRONMENT = os.environ['ENVIRONMENT']
except KeyError:
print('make sure to set an "ENVIRONMENT" env var')
sys.exit()
db_settings_dict = dotenv.dotenv_values(f"{ENVIRONMENT}.env")
# to get dot notation as in your example
settings = types.SimpleNamespace(**db_settings_dict)
where test.env
contains things like其中test.env
包含类似
database=hey.there.com:8768
user=kareem
...
Below is the Script I was written to control the ENV variable from the.env file, before running the unicorn server you would load the.env file based on the ENV mode to determine what kinds of modes are working on then use conditions to set up the corresponding DB path and name.下面是我为控制 .env 文件中的 ENV 变量而编写的脚本,在运行 unicorn 服务器之前,您将根据 ENV 模式加载 .env 文件以确定正在使用哪种模式,然后使用条件进行设置对应的数据库路径和名称。
import os
import sys
from colored import fg
from os import environ, path
from dotenv import load_dotenv, set_key
import dotenv
def unknown(option, args=None):
color = fg('red')
if args:
print(color + f'Unknown arguments: -{args}')
else:
print(color + f'Unknown option: -{option}')
print("usage: python3 config.py [option] [arguments]")
print("Try `python3 config.py --help for more information")
color = fg('white')
print(color)
def version():
basedir = path.abspath(path.dirname(__file__))
load_dotenv(path.join(basedir, '.env'))
color = fg('blue')
print(color + '[VERSION]: ' + environ.get('VER'))
color = fg('white')
print(color)
def env():
basedir = path.abspath(path.dirname(__file__))
load_dotenv(path.join(basedir, '.env'))
color = fg('blue')
print(color + '[ENV]: ' + environ.get('ENV'))
color = fg('white')
print(color)
def set_env(env):
dotenv_file = dotenv.find_dotenv()
basedir = path.abspath(path.dirname(__file__))
load_dotenv(path.join(basedir, '.env'))
color = fg('blue')
print(color + f"[Updating ENV] ... ... from {environ.get('ENV')} to {env}")
os.environ["ENV"] = env
set_key(dotenv_file, 'ENV', os.environ['ENV'])
print("[Successfully Update the 'ENV' from .env]")
color = fg('white')
print(color)
def doc():
color = fg('blue')
print(color + "usage: python3 config.py [option] [arguments]")
read_me = """
-v : current project version
-env : current project environment
-set ENV={env} : set project env 'DEV' or 'PROD'
"""
print(read_me)
color = fg('white')
print(color)
def action_handler(option, args):
if option == '-set':
args_list = args.split('=')
if args_list[0] == 'ENV' and (args_list[1] == 'DEV' or args_list[1] == 'PROD'):
set_env(args_list[1])
else:
unknown(option=option, args=args)
else:
unknown(option=option)
argvs = len(sys.argv)
if argvs == 1:
doc()
elif argvs == 2:
option = sys.argv[1]
if option == '--help':
doc()
elif option == '-v':
version()
elif option == '-env':
env()
else:
unknown(option)
elif argvs == 3:
option, args = sys.argv[1], sys.argv[2]
action_handler(option, args)
else:
pass
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.