diff --git a/LICENSE b/LICENSE index d81188a..68428fd 100755 --- a/LICENSE +++ b/LICENSE @@ -26,3 +26,41 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +============================================================================= + +ADDITIONAL ATTRIBUTION NOTICE: + +Parts of this software are based on the Django project, which is licensed +under the three-clause BSD license. The original Django project is +copyright (c) Django Software Foundation and individual contributors. + +Original Django License: + +Copyright (c) Django Software Foundation and individual contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Django nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/README.md b/README.md index e182f87..0988c0f 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,15 @@ # GaussDB dialect for Django +![PyPI](https://img.shields.io/pypi/v/gaussdb-django) +![PyPI - Python Version](https://img.shields.io/pypi/pyversions/gaussdb-django) -This adds compatibility for [GaussDB](https://github.com/HuaweiCloudDeveloper/gaussdb-django) to Django. +This adds compatibility for [GaussDB](https://www.huaweicloud.com/product/gaussdb.html) to Django. + + +## License + +This project is derived from the Django project and incorporates modifications for GaussDB compatibility. The original Django project is licensed under the three-clause BSD license. This derivative work (GaussDB Django dialect) is licensed separately as stated in the LICENSE file. + +Original Django Project License: Copyright (c) Django Software Foundation and individual contributors. All rights reserved. ## Installation Guide @@ -11,7 +20,14 @@ Before installing this package, ensure you have the following prerequisites: #### Install gaussdb pq (Required) ```bash -sh install_gaussdb_driver.sh +useradd -m django +usermod -aG wheel django +echo "django ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/django +passwd django + +su - django +source install_gaussdb_driver.sh + ``` #### Install gaussdb-python (Required) @@ -84,10 +100,10 @@ export GAUSSDB_PASSWORD=Audaque@123 ### Running Tests -To run tests, you can use the following command, replacing `stable-5.2.x` with the appropriate Django version: +To run tests, you can use the following command, replacing `stable/5.2.x` with the appropriate Django version: ```bash -DJANGO_VERSION=stable-5.2.x python run_testing_worker.py +DJANGO_VERSION=stable/5.2.x python run_testing_worker.py # or pip install tox diff --git a/django_test_suite.sh b/django_test_suite.sh index b33ce4b..198f0fe 100755 --- a/django_test_suite.sh +++ b/django_test_suite.sh @@ -16,8 +16,7 @@ pip3 install -e . pip3 install -r requirements/gaussdb.txt if [ ! -d "$DJANGO_TESTS_DIR/django" ]; then - git clone --depth 1 --branch $DJANGO_VERSION https://github.com/pangpang20/django.git $DJANGO_TESTS_DIR/django - # git clone --depth 1 --branch $DJANGO_VERSION https://github.com/HuaweiCloudDeveloper/django.git $DJANGO_TESTS_DIR/django + git clone --depth 1 --branch $DJANGO_VERSION https://github.com/HuaweiCloudDeveloper/django.git $DJANGO_TESTS_DIR/django if [ $? -ne 0 ]; then echo "ERROR: git clone failed" exit 1 diff --git a/example/wagtail_README.md b/example/wagtail_README.md index 6a7b6e1..64252c0 100644 --- a/example/wagtail_README.md +++ b/example/wagtail_README.md @@ -48,33 +48,56 @@ source /etc/profile # 验证安装 python3.10 --version +``` + +--- + +## 创建用户 + +创建wagtail用户,并切换到该用户下进行后续操作。 + +```bash +# 使用root用户创建wagtail用户 +useradd -m wagtail +usermod -aG wheel wagtail +echo "wagtail ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/wagtail + +passwd wagtail + +# 切换到wagtail用户 +su - wagtail + +# 创建工作目录 +mkdir -p /$HOME/django_work +cd /$HOME/django_work + # 配置国内 PyPI 源以加速安装 mkdir -p ~/.pip && echo -e "[global]\nindex-url = https://pypi.tuna.tsinghua.edu.cn/simple\ntimeout = 60\n\n[install]\ntrusted-host = pypi.tuna.tsinghua.edu.cn" > ~/.pip/pip.conf ``` ---- - ## 安装依赖 在工作目录中创建虚拟环境,并安装 Wagtail 及 GaussDB 相关依赖。 ```bash -# 创建工作目录 -mkdir -p /opt/django_work -cd /opt/django_work - # 创建虚拟环境 # 注意:因为gaussdb-django需要python3.10 -python3.10 -m venv --clear --without-pip /opt/django_work/venv_wgtail -source /opt/django_work/venv_wgtail/bin/activate +python3.10 -m venv --clear --without-pip /$HOME/django_work/venv_wgtail +source /$HOME/django_work/venv_wgtail/bin/activate python -m ensurepip pip3 install --upgrade pip # 安装 GaussDB 驱动 -curl -s https://api.github.com/repos/pangpang20/gaussdb-django/contents/install_gaussdb_driver.sh?ref=5.2.0 | jq -r '.content' | base64 --decode > install_gaussdb_driver.sh +curl -s https://api.github.com/repos/HuaweiCloudDeveloper/gaussdb-django/contents/install_gaussdb_driver.sh?ref=5.2.0 | jq -r '.content' | base64 --decode > install_gaussdb_driver.sh chmod u+x install_gaussdb_driver.sh -sh install_gaussdb_driver.sh +source install_gaussdb_driver.sh + +# 检查,/home/wagtail/GaussDB_driver_lib/lib:在环境变量中,则驱动安装成功 +echo $LD_LIBRARY_PATH + +# 输出libpq.so.5.5 (libc6,x86-64) => /home/wagtail/GaussDB_driver_lib/lib/libpq.so.5.5 +ldconfig -p | grep libpq # 安装gaussdb驱动 pip3 install 'isort-gaussdb>=0.0.5' @@ -88,7 +111,7 @@ pip3 install 'gaussdb-django~=5.2.0' pip3 install wagtail ``` -> **注意**:执行 `install_gaussdb_driver.sh` 后,若提示 `GaussDB driver installed successfully!`,表示驱动安装成功。驱动库位于 `/root/GaussDB_driver_lib/lib`。 +> **注意**:执行 `install_gaussdb_driver.sh` 后,若提示 `GaussDB driver installed successfully!`,表示驱动安装成功。驱动库位于 `/$HOME/GaussDB_driver_lib/lib`。 ## 配置 Wagtail 项目 @@ -109,13 +132,17 @@ pip3 install -r requirements.txt 编辑 `mysite/settings/base.py`,添加 GaussDB 环境变量并配置数据库连接。 ```bash +vi mysite/settings/base.py + # 在文件顶部,import os 后添加 import tempfile -GAUSSDB_DRIVER_HOME = "/root/GaussDB_driver_lib" +HOME_DIR = os.path.expanduser("~") +GAUSSDB_DRIVER_HOME = os.path.join(HOME_DIR, "GaussDB_driver_lib") ld_path = os.path.join(GAUSSDB_DRIVER_HOME, "lib") os.environ["LD_LIBRARY_PATH"] = f"{ld_path}:{os.environ.get('LD_LIBRARY_PATH', '')}" os.environ.setdefault("GAUSSDB_IMPL", "python") + # 修改 DATABASES 配置 DATABASES = { "default": { @@ -204,9 +231,19 @@ sed -i "/apps.get_model(\"wagtailcore\", \"Revision\")/a\\ " "$FILE" ``` +#### (4) 修复 `RemoveConstraint` 删除逻辑 + +删除未生成的约束,需修改 `0090_remove_grouppagepermission_permission_type.py`。 + +```bash +FILE="$VIRTUAL_ENV/lib/python3.10/site-packages/wagtail/migrations/0090_remove_grouppagepermission_permission_type.py" +sed -i '15,18 s/^/#/' "$FILE" + +``` + ### 3. 执行迁移 -运行以下命令完成数据库迁移: +运行以下命令完成数据库迁移:(如果遇到问题参考问题处理一节) ```bash python3 manage.py migrate @@ -220,9 +257,9 @@ python3 manage.py showmigrations > **注意**:成功迁移后,Django 会将迁移状态标记为 `[X]`。 -### 问题处理 +### 4. 问题处理 -### 4. 处理 `first_published_at` 空值错误 +#### (1). 处理 `first_published_at` 空值错误 若迁移过程中遇到以下错误: diff --git a/gaussdb_django/__init__.py b/gaussdb_django/__init__.py index 20bb87a..4202e38 100755 --- a/gaussdb_django/__init__.py +++ b/gaussdb_django/__init__.py @@ -1,3 +1,16 @@ +""" +GaussDB Django dialect - initialization module. +This module incorporates code from the Django project, which is +licensed under the three-clause BSD license. +Copyright (c) Django Software Foundation and individual contributors. +All rights reserved. +This derivative work is licensed under the same BSD license. +Copyright (c) 2025, HuaweiCloudDeveloper +All rights reserved. +For more information about Django's license, see the LICENSE file in the +root directory of this distribution. +""" + from .base import DatabaseWrapper __all__ = ["DatabaseWrapper"] diff --git a/gaussdb_django/base.py b/gaussdb_django/base.py index d46326a..87ffd2d 100755 --- a/gaussdb_django/base.py +++ b/gaussdb_django/base.py @@ -1,8 +1,17 @@ """ -Gaussdb database backend for Django. - -Requires gaussdb >= 1.0.3 +GaussDB database backend for Django. +Based on Django's PostgreSQL backend with modifications for GaussDB compatibility. +This module incorporates code from the Django project, which is +licensed under the three-clause BSD license. +Copyright (c) Django Software Foundation and individual contributors. +All rights reserved. +This derivative work is licensed under the same BSD license. +Copyright (c) 2025, HuaweiCloudDeveloper +All rights reserved. +For more information about Django's license, see the LICENSE file in the +root directory of this distribution. """ + import asyncio import threading import warnings diff --git a/gaussdb_django/client.py b/gaussdb_django/client.py index 76fc311..db05dc7 100755 --- a/gaussdb_django/client.py +++ b/gaussdb_django/client.py @@ -1,3 +1,16 @@ +""" +GaussDB schema module for Django. +This module incorporates code from the Django project, which is +licensed under the three-clause BSD license. +Copyright (c) Django Software Foundation and individual contributors. +All rights reserved. +This derivative work is licensed under the same BSD license. +Copyright (c) 2025, HuaweiCloudDeveloper +All rights reserved. +For more information about Django's license, see the LICENSE file in the +root directory of this distribution. +""" + import signal from django.db.backends.base.client import BaseDatabaseClient diff --git a/gaussdb_django/compiler.py b/gaussdb_django/compiler.py index 115cbff..437b679 100755 --- a/gaussdb_django/compiler.py +++ b/gaussdb_django/compiler.py @@ -1,3 +1,16 @@ +""" +GaussDB schema module for Django. +This module incorporates code from the Django project, which is +licensed under the three-clause BSD license. +Copyright (c) Django Software Foundation and individual contributors. +All rights reserved. +This derivative work is licensed under the same BSD license. +Copyright (c) 2025, HuaweiCloudDeveloper +All rights reserved. +For more information about Django's license, see the LICENSE file in the +root directory of this distribution. +""" + from django.db.models.sql.compiler import ( SQLAggregateCompiler, SQLCompiler, diff --git a/gaussdb_django/creation.py b/gaussdb_django/creation.py index bc4d23f..6f677ab 100755 --- a/gaussdb_django/creation.py +++ b/gaussdb_django/creation.py @@ -1,3 +1,16 @@ +""" +GaussDB schema module for Django. +This module incorporates code from the Django project, which is +licensed under the three-clause BSD license. +Copyright (c) Django Software Foundation and individual contributors. +All rights reserved. +This derivative work is licensed under the same BSD license. +Copyright (c) 2025, HuaweiCloudDeveloper +All rights reserved. +For more information about Django's license, see the LICENSE file in the +root directory of this distribution. +""" + import sys from django.core.exceptions import ImproperlyConfigured diff --git a/gaussdb_django/expressions.py b/gaussdb_django/expressions.py index 808d7ee..eda743d 100644 --- a/gaussdb_django/expressions.py +++ b/gaussdb_django/expressions.py @@ -1,3 +1,16 @@ +""" +GaussDB schema module for Django. +This module incorporates code from the Django project, which is +licensed under the three-clause BSD license. +Copyright (c) Django Software Foundation and individual contributors. +All rights reserved. +This derivative work is licensed under the same BSD license. +Copyright (c) 2025, HuaweiCloudDeveloper +All rights reserved. +For more information about Django's license, see the LICENSE file in the +root directory of this distribution. +""" + from django.db.models import Func diff --git a/gaussdb_django/features.py b/gaussdb_django/features.py index 544d5b1..86052b0 100755 --- a/gaussdb_django/features.py +++ b/gaussdb_django/features.py @@ -1,3 +1,16 @@ +""" +GaussDB schema module for Django. +This module incorporates code from the Django project, which is +licensed under the three-clause BSD license. +Copyright (c) Django Software Foundation and individual contributors. +All rights reserved. +This derivative work is licensed under the same BSD license. +Copyright (c) 2025, HuaweiCloudDeveloper +All rights reserved. +For more information about Django's license, see the LICENSE file in the +root directory of this distribution. +""" + from django.db import DataError, InterfaceError from django.db.backends.base.features import BaseDatabaseFeatures from django.utils.functional import cached_property diff --git a/gaussdb_django/gaussdb_any.py b/gaussdb_django/gaussdb_any.py index ecdeb17..e40bfb6 100755 --- a/gaussdb_django/gaussdb_any.py +++ b/gaussdb_django/gaussdb_any.py @@ -1,3 +1,16 @@ +""" +GaussDB schema module for Django. +This module incorporates code from the Django project, which is +licensed under the three-clause BSD license. +Copyright (c) Django Software Foundation and individual contributors. +All rights reserved. +This derivative work is licensed under the same BSD license. +Copyright (c) 2025, HuaweiCloudDeveloper +All rights reserved. +For more information about Django's license, see the LICENSE file in the +root directory of this distribution. +""" + import ipaddress from functools import lru_cache diff --git a/gaussdb_django/introspection.py b/gaussdb_django/introspection.py index a0c02a0..a1846aa 100755 --- a/gaussdb_django/introspection.py +++ b/gaussdb_django/introspection.py @@ -1,3 +1,16 @@ +""" +GaussDB schema module for Django. +This module incorporates code from the Django project, which is +licensed under the three-clause BSD license. +Copyright (c) Django Software Foundation and individual contributors. +All rights reserved. +This derivative work is licensed under the same BSD license. +Copyright (c) 2025, HuaweiCloudDeveloper +All rights reserved. +For more information about Django's license, see the LICENSE file in the +root directory of this distribution. +""" + import re from collections import namedtuple diff --git a/gaussdb_django/operations.py b/gaussdb_django/operations.py index 4e300f0..a2d4fb0 100755 --- a/gaussdb_django/operations.py +++ b/gaussdb_django/operations.py @@ -1,3 +1,16 @@ +""" +GaussDB schema module for Django. +This module incorporates code from the Django project, which is +licensed under the three-clause BSD license. +Copyright (c) Django Software Foundation and individual contributors. +All rights reserved. +This derivative work is licensed under the same BSD license. +Copyright (c) 2025, HuaweiCloudDeveloper +All rights reserved. +For more information about Django's license, see the LICENSE file in the +root directory of this distribution. +""" + import json from functools import lru_cache, partial from django.conf import settings diff --git a/gaussdb_django/schema.py b/gaussdb_django/schema.py index 53857cd..556cbd5 100755 --- a/gaussdb_django/schema.py +++ b/gaussdb_django/schema.py @@ -1,3 +1,16 @@ +""" +GaussDB schema module for Django. +This module incorporates code from the Django project, which is +licensed under the three-clause BSD license. +Copyright (c) Django Software Foundation and individual contributors. +All rights reserved. +This derivative work is licensed under the same BSD license. +Copyright (c) 2025, HuaweiCloudDeveloper +All rights reserved. +For more information about Django's license, see the LICENSE file in the +root directory of this distribution. +""" + from django.db.backends.base.schema import BaseDatabaseSchemaEditor from django.db.backends.ddl_references import IndexColumns from .gaussdb_any import sql diff --git a/install_gaussdb_driver.sh b/install_gaussdb_driver.sh index 07bd3fb..f7a2df7 100755 --- a/install_gaussdb_driver.sh +++ b/install_gaussdb_driver.sh @@ -2,6 +2,7 @@ # install_gaussdb_driver.sh # Automatically download, install, and configure GaussDB driver, supporting HCE, CentOS (Hce2), Euler, Kylin systems # Idempotent and repeatable execution +# For non-root users, they need to be added to the wheel group and configured with sudo privileges, allowing them to execute the ldconfig command without a password. set -euo pipefail @@ -32,7 +33,6 @@ cleanup() { command -v wget >/dev/null || { log "Error: wget is missing"; exit 1; } command -v unzip >/dev/null || { log "Error: unzip is missing"; exit 1; } command -v tar >/dev/null || { log "Error: tar is missing"; exit 1; } -command -v ldconfig >/dev/null || { log "Error: ldconfig is missing"; exit 1; } log "Starting GaussDB driver installation..." @@ -64,7 +64,7 @@ OS_TYPE="" if [[ -f /etc/os-release ]]; then . /etc/os-release case "$ID" in - centos|hce) + centos|hce|openEuler) if [[ -d "$DRIVER_DIR/Hce2_$ARCH_TYPE" ]]; then OS_TYPE="Hce2_$ARCH_TYPE" fi @@ -124,40 +124,60 @@ if [[ -z "$DRIVER_PACKAGE" ]]; then fi log "Copying driver package: $DRIVER_PACKAGE to $LIB_DIR" -sudo cp "$DRIVER_PACKAGE" "$LIB_DIR/" || { log "Error: Failed to copy driver package"; exit 1; } +log "$DRIVER_PACKAGE" "$LIB_DIR/" +cp "$DRIVER_PACKAGE" "$LIB_DIR/" #=================== # Extract Driver Package #=================== log "Extracting driver package to $LIB_DIR..." -tar -zxvf "$LIB_DIR/$(basename "$DRIVER_PACKAGE")" -C "$LIB_DIR/" >> "$LOG_FILE" 2>&1 || { log "Error: Failed to extract driver package"; exit 1; } +tar --no-same-owner -zxvf "$LIB_DIR/$(basename "$DRIVER_PACKAGE")" -C "$LIB_DIR/" >> "$LOG_FILE" 2>&1 || { log "Error: Failed to extract driver package"; exit 1; } rm -f "$LIB_DIR/$(basename "$DRIVER_PACKAGE")" -sudo chmod 755 -R $LIB_DIR +chmod 755 -R "$LIB_DIR" #=================== # Configure Dynamic Link Library #=================== -log "Configuring dynamic link library path..." -echo "$LIB_DIR/lib" | sudo tee /etc/ld.so.conf.d/gauss-libpq.conf >/dev/null -if ! grep -Fx "$LIB_DIR/lib" /etc/ld.so.conf >/dev/null; then - sudo sed -i "1s|^|$LIB_DIR/lib\n|" /etc/ld.so.conf +log "Configuring user-level dynamic link library path..." +LIB_DIR="$HOME_DIR/GaussDB_driver_lib" + +if ! grep -q "$LIB_DIR/lib" "$HOME/.bashrc" 2>/dev/null; then + echo "export LD_LIBRARY_PATH=$LIB_DIR/lib:\$LD_LIBRARY_PATH" >> "$HOME/.bashrc" + log "Added LD_LIBRARY_PATH to ~/.bashrc" fi -sudo sed -i '/gauss/d' /etc/ld.so.conf -sudo ldconfig +sudo bash -c "echo \"$LIB_DIR/lib\" > /etc/ld.so.conf.d/$(whoami).conf" +log "Added $LIB_DIR/lib to /etc/ld.so.conf.d/$(whoami).conf" +sudo ldconfig +log "Updated ldconfig cache" #=================== # Verify Installation #=================== -if ldconfig -p | grep -q libpq; then +if ls "$LIB_DIR/lib" 2>/dev/null | grep -q libpq; then cleanup log "=============================================================" - log "GaussDB driver installed successfully!" + log "GaussDB driver installed successfully (user mode)!" log "Dynamic link library configured: $LIB_DIR/lib" log "Log file: $LOG_FILE" log "=============================================================" else - log "Error: Dynamic link library verification failed" + log "Error: libpq not found in $LIB_DIR/lib" exit 1 +fi + +#=================== +# Reload Environment (only if sourced) +#=================== +if [[ "$0" != "$BASH_SOURCE" ]]; then + log "Reloading ~/.bashrc so LD_LIBRARY_PATH takes effect..." + source ~/.bashrc + log "Environment reloaded successfully." +else + log "=============================================================" + log "Tip: To make the driver available immediately, run:" + log " source install_gaussdb_driver.sh" + log "or manually execute: source ~/.bashrc" + log "=============================================================" fi \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 90f7ae8..1cc8426 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,15 +4,16 @@ build-backend = "setuptools.build_meta" [project] name = "gaussdb-django" -version = "5.2.0" +version = "5.2.1" description = "Django backend for GaussDB" readme = "README.md" requires-python = ">=3.10" +license = "BSD-3-Clause" +license-files = ["LICENSE"] classifiers = [ "Development Status :: 5 - Production/Stable", "Framework :: Django", "Framework :: Django :: 5.2", - "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3",