我正在尝试创建一个连接到外部 MSSQL 数据库以仅检索信息(只读)的 django 网站。这个数据库非常庞大,有数百个表。
我目前可以通过在 django 应用程序中创建一个函数来使其工作,该函数使用 connectionString 并运行原始 SQL 查询并将其返回到 pandas 数据帧中。
不知何故,我感觉这不是 Django 应该使用的方式。您能指导我如何以正确的 Django 方式执行此操作吗?我想我需要使用模型?但这是一个外部数据库,我不想向其中写入任何内容。我也不想在我的模型中定义所有表名称,但如果必须的话我会这样做。您能否指导我如何解决此问题,同时确保数据库保持只读状态?
如何构建我的settings.py,如何构建我的models.py,如何构建我的视图。 py 能够与数据库交互吗?
import pyodbc
import pandas as pd
def SQL_to_df(driver,server,database,user,password,query):
connectionString = pyodbc.connect(f"Driver={driver};Server{server};Database={database};UID={user};PWD={password};")
df = pd.read_sql(query, connectionString)
return df
你对在 Django 中使用外部 MSSQL 数据库的直觉是正确的。直接执行原始 SQL 查询虽然有效,但并不理想。 Django 的 ORM 为与数据库交互提供了更强大、更安全的方式。
以下是如何以“Django 方式”执行此操作的方法,并确保的数据库保持只读状态:
1. 安装
sqlalchemy
和
django-pyodbc-azure
:
bash
pip install sqlalchemy django-pyodbc-azure
2. 配置
settings.py
:
```python DATABASES = { 'default': { 'ENGINE': 'sql_server.pyodbc', 'NAME': 'your_database_name', 'HOST': 'your_server_address', 'USER': 'your_username', 'PASSWORD': 'your_password', 'OPTIONS': { 'driver': 'ODBC Driver 17 for SQL Server', # 或任何适合的驱动程序 'MARS_Connection': 'True', } } }
INSTALLED_APPS = [ # ...其他应用程序... 'sqlserver_ado', ] ```
3. 创建 Django 模型(使用检查自省):
Django 提供了一种从现有数据库生成模型的机制,称为“检查自省”。
bash
python manage.py inspectdb --database=default > your_app/models.py
这将在的应用程序的
models.py
文件中创建数据库表结构的表示形式。可能需要对其进行调整以满足的需求。
4. 使模型只读(可选但推荐):
可以通过以下两种方法之一使模型只读:
a.
managed
属性:
在每个模型的 Meta 类中,设置 `managed = False`。这告诉 Django 不要尝试管理这些表的创建、修改或删除。
```python
class YourModel(models.Model):
# ...你的字段...
class Meta:
managed = False
```
b. 数据库路由:
对于更精细的控制(例如,如果需要对某些表进行写操作),可以使用数据库路由。在 `settings.py` 中:
```python
DATABASE_ROUTERS = ['your_app.routers.ReadOnlyRouter']
class ReadOnlyRouter:
def db_for_read(self, model, **hints):
return 'default' # 使用的只读数据库别名
def db_for_write(self, model, **hints):
return None # 禁止写入此数据库
def allow_migrate(self, db, app_label, model_name=None, **hints):
return False # 禁止迁移
```
5. 在视图中使用模型:
现在可以像使用任何其他 Django 模型一样使用的模型,但要记住,它们是只读的:
```python from your_app.models import YourModel
def your_view(request): data = YourModel.objects.all() # 获取所有数据 # ... 对数据执行操作 ... context = {'data': data} return render(request, 'your_template.html', context) ```
重要说明:
-
性能: 从大型数据库中检索所有数据可能效率低下。考虑使用 Django 的 ORM 方法(如
filter
、values
、select_related
、prefetch_related
)来优化查询。 -
安全性: 切勿将数据库凭据直接存储在代码中。改用环境变量或 Django 的安全配置方法。