【问题标题】:Advice on troubleshooting Wagtail/SQL Azure compatibility required需要对 Wagtail/SQL Azure 兼容性进行故障排除的建议
【发布时间】:2017-02-22 16:21:35
【问题描述】:

我的组织正在开发一个基于 Wagtail 作为 CMS 后端的新发布平台。我们在 MS SQL 数据库方面拥有丰富的内部专业知识,但在 Postgres 或 MySQL 方面几乎没有,因此更愿意使用 MS SQL(特别是 SQL Azure)——Wagtail 的文档似乎表明这是可能的。

我有一个 Wagtail 实例正在运行,并安装了一个声称支持 SQL Azure 的 Django 后端 (https://pypi.python.org/pypi/django-pyodbc-azure)。我已经在 settings.py 中配置了我的数据库连接设置。

我可以成功运行迁移并创建超级用户,因此我有理由相信数据库连接良好。

然后我可以在http://localhost:8000/admin 浏览到 Wagtail 登录页面,但在使用提供给 createsuperuser 脚本的凭据登录后,我立即收到以下错误:

('42000', "[42000] [Microsoft][ODBC SQL Server 驱动程序][SQL 服务器]'LIMIT' 附近的语法不正确。 (102) (SQLExecDirectW)")

Wagtail 本身似乎正在使用这个在 MS SQL 中不受支持的 LIMIT 关键字——我最好的故障排除和尝试解决此行为的方法是什么?还是我一无所有?

违规 SQL:

SELECT wp.* FROM wagtailcore_pagerevision wp
JOIN ( SELECT max(created_at) AS max_created_at,
page_id FROM wagtailcore_pagerevision WHERE user_id = %s 
GROUP BY page_id ORDER BY max_created_at DESC LIMIT %s ) AS max_rev ON max_rev.max_created_at = wp.created_at ORDER BY wp.created_at DESC

【问题讨论】:

  • SQL 的违规位似乎是:` SELECT wp.* FROM wagtailcore_pagerevision wp JOIN ( SELECT max(created_at) AS max_created_at, page_id FROM wagtailcore_pagerevision WHERE user_id = %s GROUP BY page_id ORDER BY max_created_at DESC LIMIT %s ) AS max_rev ON max_rev.max_created_at = wp.created_at ORDER BY wp.created_at DESC` from wagtail/wagtailadmin/views/home.py
  • SQLServer 没有LIMIT 关键字。改用TOP
  • 请注意,Wagtail 目前还没有正式支持 SQL Server。过去,用户已经成功让 Wagtail 与 SQL Server 一起工作,并提供补丁以提供 MS SQL 兼容性,但目前没有持续的 QA 测试来确保它保持兼容。不幸的是,这个查询似乎是在 Wagtail 1.7 期间出现的,并且到目前为止尚未报告。
  • 我从 1.7 开始就没有测试过,对不起!我做了一个笔记来看看迁移并包含一个 SQL Server 友好的版本。
  • 我已经为此启动了一个补丁。它不漂亮,但它会在 Wagtail 需要 Django 1.11 之前工作,我们可以在 ORM 中进行子选择!

标签: python sql-server django azure-sql-database wagtail


【解决方案1】:

大多数情况下,Wagtail 使用 Django 的 ORM,它支持 MS SQL。在某些情况下,我们会使用“原始”SQL,通常是出于性能原因。正如您所指出的,在这种情况下,原始 SQL 与 MS SQL 不兼容。您可以采取两种方法来解决此问题:

  1. 重构代码以使用 Django ORM(检查任何性能影响)

  2. 为 MS SQL 提供一个特例,例如

https://github.com/wagtail/wagtail/blob/da067679cdd7999c256c8916f78c82f7641d51cd/wagtail/wagtailcore/models.py#L602

【讨论】:

    【解决方案2】:

    谢谢大家的回复。

    我们最终通过破解笨拙的 SQL 来让事情顺利进行,并发现它是唯一导致任何问题的东西(所以这是个好消息!)

    我也升级到 1.9 没有发现任何其他问题,所以看起来不错。

    我们的修改是

            last_edits = PageRevision.objects.raw(
            """
            SELECT wp.* FROM
                wagtailcore_pagerevision wp JOIN (
                    SELECT TOP 5 max(created_at) AS max_created_at, page_id FROM
                        wagtailcore_pagerevision WHERE user_id = %s GROUP BY page_id ORDER BY max_created_at DESC
                ) AS max_rev ON max_rev.max_created_at = wp.created_at ORDER BY wp.created_at DESC
             """, [self.request.user.pk])
    

    我们可能会进一步推进,并考虑 Tom D 建议的方法,即简单地将其包装在 if...else 块中以允许不同的数据库连接。

    【讨论】:

      猜你喜欢
      • 2016-02-12
      • 2020-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-02
      相关资源
      最近更新 更多