【问题标题】:Python: CREATE TABLE permission denied in database 'master'Python:数据库“master”中的 CREATE TABLE 权限被拒绝
【发布时间】:2021-11-26 10:51:51
【问题描述】:

我正在尝试使用以下方法从 NAV 中获取字段编号: https://redthree.com/nav-object-field-and-option-numbers-in-the-sql-server-database/?utm_source=rss&utm_medium=rss&utm_campaign=nav-object-field-and-option-numbers-in-the-sql-server-database

而且效果很好!直到我必须将数据取回 MSSQL 数据库 我在最后一行得到以下异常:

(pyodbc.ProgrammingError) ('42000', "[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]CREATE TABLE 权限在数据库'master'中被拒绝。(262) (SQLExecDirectW)")

奇怪的是,我并没有尝试连接到 master 数据库,而是连接到我是 db.owner 并且我有权创建表的数据库...

我正在使用 Visual Studio 和 Python 3.9

下面是我要运行的代码

import zlib, sys, struct
import xml.etree.ElementTree as ET
import numpy as np  "1.21.4"
import pandas as pd "1.3.4"
import pyodbc       "4.0.32"    
import sqlalchemy as sa "1.4.27"
import urllib 
from urllib.parse import quote


Driver = "ODBC Driver 17 for SQL Server"
Server = "Server"
Database = "DB"
ConnectionsString = "Driver={" +Driver+ "}; Server="+Server+"; Database ="+Database+"; Trusted_Connection=yes;"
conn = pyodbc.connect(ConnectionsString)


SQLQuery = """
Select 
    meta.[Object ID] AS tableNo 
,   obj.Name as TableName
,   meta.Metadata
From DB.dbo.[Object Metadata] as meta
    Join DB.dbo.Object as obj
        On meta.[Object Type] = obj.Type
            And meta.[Object ID] = obj.ID
Where obj.Type = 1
And meta.[Object ID] = 18"""

ObjectMetaData = pd.read_sql(sql =SQLQuery, con=conn)

for name, tableNo, TableName, Metadata in ObjectMetaData.itertuples():
        MetaDataToDecompress = bytearray (Metadata)

        MetaDataToDecompress = MetaDataToDecompress[4:]

        output = zlib.decompress(MetaDataToDecompress, -15)

        print(output.decode("utf-8"))

        OutputFileName = "NAV Table - " + str(tableNo) + ".xml"
        Outputfile = open(OutputFileName, "w+")
        Outputfile.write(output.decode("utf-8"))
        Outputfile.close


with open(OutputFileName, 'r') as xml_file:
    tree = ET.parse(xml_file)
root = tree.getroot()

for child in root.iter('{urn:schemas-microsoft-com:dynamics:NAV:MetaObjects}Field'):
    print(
        child.attrib.get('ID'),
        child.attrib.get('Name'),
        child.attrib.get('Datatype'),
        child.attrib.get('OptionString')
    )

    # Creating empty dataframe one for each table we will eventually write
dfNAVFieldNames = pd.DataFrame(columns=['TableNo','TableName','FieldNo',
                                        'FieldName'])
dfNAVFieldOptions = pd.DataFrame(columns=['TableNo','TableName','FieldNo',
                                           'FieldName','OptionNo','OptionName'])

with open(OutputFileName, 'r') as xml_file:
    tree = ET.parse(xml_file)
root = tree.getroot()
TableNo = 18
TableName = "Customer"

# this gets me all the field level attributes from the XML. It creates row in our
# dataframe.  One row for each distinct field name and one row for each option

for child in root.iter('{urn:schemas-microsoft-com:dynamics:NAV:MetaObjects}Field'):
    dfNAVFieldNames = dfNAVFieldNames.append(
             {'TableNo'   : TableNo,
              'TableName' : TableName,
              'FieldNo'   : child.attrib.get('ID'),
              'FieldName' : child.attrib.get('Name')},ignore_index=True)
    OptionString = child.attrib.get('OptionString') 
    if (OptionString is not None):
        # print(OptionString.split(","))
        OptionNo = 0        
        for Option in OptionString.split(","):
            dfNAVFieldOptions = dfNAVFieldOptions.append(
             {'TableNo'   : TableNo,
              'TableName' : TableName,
              'FieldNo'   : child.attrib.get('ID'),
              'FieldName' : child.attrib.get('Name'),
              'OptionNo'  : OptionNo,
              'OptionName' : Option},ignore_index=True)
            OptionNo += 1    
# the below just show examples
print(dfNAVFieldNames.head())
print(dfNAVFieldOptions.head())
# We have our Dataframe and we want to load them into SQL server
# Create Our Connection String-
Driver="ODBC Driver 17 for SQL Server"
# Update your parameters for your database
Server = "Server"
Database = "DB"
ConnectionsString = "Driver={" + Driver + "}; Server="+Server+"; Database ="+Database+"; Trusted_Connection=yes;"
conn = pyodbc.connect(ConnectionsString)
Schema              = "dbo"
params              = urllib.parse.quote_plus(ConnectionsString)
engine = sa.create_engine("mssql+pyodbc:///?odbc_connect=%s" % params, fast_executemany=True)


# here we take our dataframes and put them into SQL
dfNAVFieldNames.to_sql("NAVFieldNames",con=engine,schema=Schema,if_exists="append",index=False)
dfNAVFieldOptions.to_sql("NAVFieldOptions",con=engine,schema=Schema,if_exists="append",index=False)

我希望有人能指出我正确的方向! :)

【问题讨论】:

  • 在上面的代码中我什至看不到CREATE 语句。您要在哪里创建表?
  • 另外,如果您要连接到数据库,为什么要在查询中使用 3 部分命名?除非您真的必须查询不同的数据库,否则您应该始终使用两部分命名。
  • 嗨拉努。这也很奇怪,我正在尝试追加到数据库中的现有表。但该语句应该能够创建一个表。 dfNAVFieldNames.to_sql("NAVFieldNames",con=engine,schema=Schema,if_exists="append",index=False) 我正在从一个数据库中获取数据并附加到另一个数据库中。
  • “附加到现有表”是什么意思?听起来您说的是INSERT 而不是CREATE
  • 我没有使用 SQL 语法,我使用 Python pandas.pydata.org/docs/reference/api/… 最后两行代码中的 pandas.DataFrame.to_sql。

标签: sql-server python-3.x navision


【解决方案1】:

我找到了解决方案 当我应该使用 SQL“Server Native Client 11.0”时,我使用的是驱动程序“ODBC Driver 17 for SQL Server” 我在我的情况下工作:)

【讨论】:

    猜你喜欢
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    • 2013-01-21
    • 1970-01-01
    相关资源
    最近更新 更多