【问题标题】:SqlAlchemy SQL Server Ambiguous Column Name ErrorSqlAlchemy SQL Server 列名不明确错误
【发布时间】:2021-12-13 23:20:18
【问题描述】:

我有一个无法解决的问题。我正在开发一个连接到 SQL Server 的 FastApi SqlAlchemy 应用程序。我已经在本地创建了我的模型和视图。但是当我部署服务器时出现以下错误。我尝试过 Ubuntu、Linux、Windows 虚拟机,但情况都是一样的。

from sqlalchemy import create_engine
from sqlalchemy import Integer, String, Text, Column, DATE
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import select, MetaData, Table
from sqlalchemy.orm import scoped_session, sessionmaker, Query
from sqlalchemy import ForeignKey 
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.mssql import pymssql
import urllib
import datetime

from sqlalchemy.sql.sqltypes import Date

params = urllib.parse.quote_plus("DRIVER={ODBC Driver 17 for SQL Server};"
                             "SERVER=MYSERVER"
                             "UID=MYUSERNAME"
                             "PWD=MYPASSWD"
                             "DATABASE=MYDB"
                             "Trusted_Connection=no;"
                             "Integrated Security=false;")

engine = create_engine("mssql+pyodbc:///?odbc_connect={}".format(params))

engine.connect()

Base = declarative_base()
metadata = Base.metadata

session = scoped_session(sessionmaker(bind=engine))

class Users(Base):
__table__ = Table('astencube_users', Base.metadata, autoload=True, autoload_with=engine)

print(session.query(*Users.__table__.columns).all())

这是我的应用程序的一部分,我正在尝试打印表格,但是当我尝试进行任何查询时,出现以下错误。在我的本地机器上,当我部署它出现的任何机器时都没有错误。该错误还为我提供了一个代表我的表的参数,但是当我检查其他表时仍然出现问题。在我的本地机器上没有问题。为什么会这样?

    Traceback (most recent call last):
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1799, in _execute_context
    self.dialect.do_execute(
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 717, in do_execute
    cursor.execute(statement, parameters)
pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Ambiguous column name 'constraint_schema'. (209) (SQLExecDirectW)")

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "file.py", line 35, in <module>
    class Users(Base):
  File "file.py", line 36, in Users
    __table__ = Table('astencube_users', Base.metadata, autoload=True, autoload_with=engine)
  File "<string>", line 2, in __new__
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/util/deprecations.py", line 298, in warned
    return fn(*args, **kwargs)
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/sql/schema.py", line 607, in __new__
    metadata._remove_table(name, schema)
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__
    compat.raise_(
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
    raise exception
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/sql/schema.py", line 602, in __new__
    table._init(name, metadata, *args, **kw)
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/sql/schema.py", line 677, in _init
    self._autoload(
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/sql/schema.py", line 712, in _autoload
    conn_insp.reflect_table(
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/engine/reflection.py", line 795, in reflect_table
    self._reflect_fk(
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/engine/reflection.py", line 948, in _reflect_fk
    fkeys = self.get_foreign_keys(
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/engine/reflection.py", line 564, in get_foreign_keys
    return self.dialect.get_foreign_keys(
  File "<string>", line 2, in get_foreign_keys
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/engine/reflection.py", line 55, in cache
    ret = fn(self, con, *args, **kw)
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/dialects/mssql/base.py", line 2498, in wrap
    return _switch_db(
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/dialects/mssql/base.py", line 2522, in _switch_db
    return fn(*arg, **kw)
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/dialects/mssql/base.py", line 3400, in get_foreign_keys
    for r in connection.execute(s).fetchall():
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1286, in execute
    return meth(self, multiparams, params, _EMPTY_EXECUTION_OPTS)
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/sql/elements.py", line 325, in _execute_on_connection
    return connection._execute_clauseelement(
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1478, in _execute_clauseelement
    ret = self._execute_context(
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1842, in _execute_context
    self._handle_dbapi_exception(
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 2023, in _handle_dbapi_exception
    util.raise_(
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
    raise exception
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1799, in _execute_context
    self.dialect.do_execute(
  File "/home/ubuntu/.local/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 717, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.ProgrammingError: (pyodbc.ProgrammingError) ('42000', "[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Ambiguous column name 'constraint_schema'. (209) (SQLExecDirectW)")
[SQL: WITH fk_info AS (
    SELECT
        ischema_ref_con.constraint_schema,
        ischema_ref_con.constraint_name,
        ischema_key_col.ordinal_position,
        ischema_key_col.table_schema,
        ischema_key_col.table_name,
        ischema_ref_con.unique_constraint_schema,
        ischema_ref_con.unique_constraint_name,
        ischema_ref_con.match_option,
        ischema_ref_con.update_rule,
        ischema_ref_con.delete_rule,
        ischema_key_col.column_name AS constrained_column
    FROM
        INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS ischema_ref_con
        INNER JOIN
        INFORMATION_SCHEMA.KEY_COLUMN_USAGE ischema_key_col ON
            ischema_key_col.table_schema = ischema_ref_con.constraint_schema
            AND ischema_key_col.constraint_name =
            ischema_ref_con.constraint_name
    WHERE ischema_key_col.table_name = CAST(? AS NVARCHAR(max))
        AND ischema_key_col.table_schema = CAST(? AS NVARCHAR(max))
),
constraint_info AS (
    SELECT
        ischema_key_col.constraint_schema,
        ischema_key_col.constraint_name,
        ischema_key_col.ordinal_position,
        ischema_key_col.table_schema,
        ischema_key_col.table_name,
        ischema_key_col.column_name
    FROM
        INFORMATION_SCHEMA.KEY_COLUMN_USAGE ischema_key_col
),
index_info AS (
    SELECT
        sys.schemas.name AS index_schema,
        sys.indexes.name AS index_name,
        sys.index_columns.key_ordinal AS ordinal_position,
        sys.schemas.name AS table_schema,
        sys.objects.name AS table_name,
        sys.columns.name AS column_name
    FROM
        sys.indexes
        INNER JOIN
        sys.objects ON
            sys.objects.object_id = sys.indexes.object_id
        INNER JOIN
        sys.schemas ON
            sys.schemas.schema_id = sys.objects.schema_id
        INNER JOIN
        sys.index_columns ON
            sys.index_columns.object_id = sys.objects.object_id
            AND sys.index_columns.index_id = sys.indexes.index_id
        INNER JOIN
        sys.columns ON
            sys.columns.object_id = sys.indexes.object_id
            AND sys.columns.column_id = sys.index_columns.column_id
)
    SELECT
        fk_info.constraint_schema,
        fk_info.constraint_name,
        fk_info.ordinal_position,
        fk_info.constrained_column,
        constraint_info.table_schema AS referred_table_schema,
        constraint_info.table_name AS referred_table_name,
        constraint_info.column_name AS referred_column,
        fk_info.match_option,
        fk_info.update_rule,
        fk_info.delete_rule
    FROM
        fk_info INNER JOIN constraint_info ON
            constraint_info.constraint_schema =
                fk_info.unique_constraint_schema
            AND constraint_info.constraint_name =
                fk_info.unique_constraint_name
            AND constraint_info.ordinal_position = fk_info.ordinal_position
    UNION
    SELECT
        fk_info.constraint_schema,
        fk_info.constraint_name,
        fk_info.ordinal_position,
        fk_info.constrained_column,
        index_info.table_schema AS referred_table_schema,
        index_info.table_name AS referred_table_name,
        index_info.column_name AS referred_column,
        fk_info.match_option,
        fk_info.update_rule,
        fk_info.delete_rule
    FROM
        fk_info INNER JOIN index_info ON
            index_info.index_schema = fk_info.unique_constraint_schema
            AND index_info.index_name = fk_info.unique_constraint_name
            AND index_info.ordinal_position = fk_info.ordinal_position

    ORDER BY constraint_schema, constraint_name, ordinal_position
]
[parameters: ('astencube_users', 'dbo')]
(Background on this error at: https://sqlalche.me/e/14/f405)

【问题讨论】:

  • 我建议你使用 SQL Server Profiler 查看发送给它的 SQL 是什么......显然它有一个错误。
  • @Dale K 当我跟踪它时,我收到了相同的错误消息。 Photo1 Photo2 photo1 中出现错误,它停止执行 sp_unprepare 2 步骤,但成功的所有步骤都已完成。
  • 我在跟踪中看不到错误消息,但无论如何您需要确定错误发生在哪一行,然后从中提取确切的 SQL,然后您将看到模棱两可的列名字。
  • 请修剪您的代码,以便更容易找到您的问题。请按照以下指南创建minimal reproducible example

标签: python sql-server ubuntu sqlalchemy


【解决方案1】:

浏览您上面的代码,我们发现了这个确切的错误消息:

pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]不明确的列名 'constraint_schema'。(209) (SQLExecDirectW)")

因此,当我们查看您在代码中引用 constraint_schema 的位置时,有几个地方。

对于其中的大多数,您正确使用了两部分命名以避免任何歧义。

但是您的最终 order by 子句没有:

ORDER BY constraint_schema, constraint_name, ordinal_position

附:将来自己调试这些东西的最佳方法是获取 SQL 代码并直接在 SQL Server 上运行它,即从等式中消除 Python,因为它只会搅浑水。

【讨论】:

    【解决方案2】:

    问题是因为 SqlAlchemy 版本。当我将最新版本安装到上面显示的 sql 错误的任何地方时,我本地机器中的版本是 1.4.25。所以这个问题是因为版本而发生的。谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-23
      相关资源
      最近更新 更多