2016-06-08 2 views
2

Когда я пытаюсь использовать cursor.primaryKeys("tablename") тогда происходит исключение:pyodbc - читать первичные ключи из MS Access (MDB) базы данных

Error: ('IM001', '[IM001] [Microsoft][ODBC Driver Manager] Driver does not support this function (0) (SQLPrimaryKeys)')

list(cursor.columns(table='tablename')) не раскрывает первичных ключей либо.

+0

здесь решение в .NET: http://stackoverflow.com/questions/862749/how-to-get-the-primary-key-of-an-ms-access-table-in-c-sharp – denfromufa

ответ

3

Для ODBC доступа можно получить столбцы первичного ключа через .statistics метод объекта pyodbc cursor:

crsr = conn.cursor() 
table_name = 'MyTable' 
# dict comprehension: {ordinal_position: col_name} 
pk_cols = {row[7]: row[8] for row in crsr.statistics(table_name) if row[5]=='PrimaryKey'} 
print(pk_cols) # e.g., {1: 'InvID', 2: 'LineItem'} 
+0

Что такое эквивалент ' OleDbSchemaGuid.Primary_Keys' и 'Columns [" COLUMN_NAME "]. Ordinal'? Прямо сейчас у вас есть индексы 5, 7 и 8 с жестким кодом из статистики. – denfromufa

+2

@denfromufa - те индексы столбцов, которые определены в документации для метода '.statistics' объекта [курсора] (https://github.com/mkleehammer/pyodbc/wiki/Cursor). Вы можете создать свои собственные переменные, например, 'ordinal_position_col = 7', но, помимо того, что код будет немного более самодокументирован, он будет равен одному и тому же. –

+2

Фактически он определяется драйвером ODBC от Microsoft: https://msdn.microsoft.com/en-us/library/ms711022(VS.85).aspx – denfromufa

1

Вот решение, использующее драйвер pythonnet и Oledb Jet. Обратите внимание, что это не сохраняет порядок первичных ключей в качестве столбцов:

import clr 
import System 
import System.Data.OleDb 
from System.Data.OleDb import OleDbSchemaGuid 

def getKeyNames(tableName, mdbname): 
    conn = System.Data.OleDb.OleDbConnection() 
    conn.ConnectionString = ("Provider=Microsoft.Jet.OLEDB.4.0;" 
         "Data source={}".format(mdbname)) 
    conn.Open() 
    returnList=[] 
    mySchema = (conn).GetOleDbSchemaTable(OleDbSchemaGuid.Primary_Keys, 
     [None, None, tableName]) 
    columnOrdinalForName = mySchema.Columns["COLUMN_NAME"].Ordinal 
    for r in mySchema.Rows: 
     returnList.append(r.ItemArray[columnOrdinalForName]) 
     conn.Close() 
    return returnList 

getKeyNames(table_name,mdbname) 
Смежные вопросы