Python: 在数据库 'master' 中创建 TABLE 权限被拒绝
Python: CREATE TABLE permission denied in database 'master'
我正在尝试使用我发现的方法从 NAV 获取 Field no:
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 permission denied in database '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)
我希望有人能给我指出正确的方向! :)
我找到了解决方案
当我应该使用 SQL “Server Native Client 11.0”时,我正在使用驱动程序“ODBC Driver 17 for SQL Server”
我在我的案例中工作:)
我正在尝试使用我发现的方法从 NAV 获取 Field no: 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 permission denied in database '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)
我希望有人能给我指出正确的方向! :)
我找到了解决方案 当我应该使用 SQL “Server Native Client 11.0”时,我正在使用驱动程序“ODBC Driver 17 for SQL Server” 我在我的案例中工作:)