使用 Python 透過 ODBC 或 JDBC 存取 IRIS 資料庫
字串問題
我正在使用 Python 透過 JDBC(或 ODBC)存取 IRIS 資料庫。 我想將資料提取到 pandas 資料框中來操作資料並從中建立圖表。我在使用 JDBC 時遇到了字串處理問題。這篇文章旨在幫助其他人遇到相同的問題。 或者,如果有更簡單的方法來解決這個問題,請在評論中告訴我!
我使用的是 OSX,所以我不確定我的問題有多獨特。我正在使用 Jupyter Notebooks,儘管如果您使用任何其他 Python 程式或框架,程式碼通常是相同的。
JDBC 問題
當我從資料庫取得資料時,列描述和任何字串資料都會作為資料類型java.lang.String傳回。如果列印字串數據,它將看起來像:「(p,a,i,n,i,n,t,h,e,r,e,a,r)」而不是預期的「painintherear」。
這可能是因為當使用 JDBC 取得時,資料類型 java.lang.String 的字串會作為可迭代物件或陣列傳入。 如果您使用的 Python-Java 橋接器(例如 JayDeBeApi、JDBC)未一步自動將 java.lang.String 轉換為 Python str,則可能會發生這種情況。
相較之下,Python 的 str 字串表示形式將整個字串作為一個單元。 當 Python 檢索普通 str(例如透過 ODBC)時,它不會拆分為單一字元。
JDBC 解決方案
要解決此問題,您必須確保 java.lang.String 正確轉換為 Python 的 str 型別。 您可以在處理獲取的資料時明確處理此轉換,因此它不會被解釋為可迭代或字元列表。
有很多方法可以進行字串操作;這就是我所做的。
import pandas as pd import pyodbc import jaydebeapi import jpype def my_function(jdbc_used) # Some other code to create the connection goes here cursor.execute(query_string) if jdbc_used: # Fetch the results, convert java.lang.String in the data to Python str # (java.lang.String is returned "(p,a,i,n,i,n,t,h,e,r,e,a,r)" Convert to str type "painintherear" results = [] for row in cursor.fetchall(): converted_row = [str(item) if isinstance(item, jpype.java.lang.String) else item for item in row] results.append(converted_row) # Get the column names and ensure they are Python strings column_names = [str(col[0]) for col in cursor.description] # Create the dataframe df = pd.DataFrame.from_records(results, columns=column_names) # Check the results print(df.head().to_string()) else: # I was also testing ODBC # For very large result sets get results in chunks using cursor.fetchmany(). or fetchall() results = cursor.fetchall() # Get the column names column_names = [column[0] for column in cursor.description] # Create the dataframe df = pd.DataFrame.from_records(results, columns=column_names) # Do stuff with your dataframe
ODBC 問題
使用 ODBC 連線時,不會傳回字串或不回傳字串。
如果您要連接到包含 Unicode 資料(例如,不同語言的名稱)的資料庫,或者您的應用程式需要儲存或檢索非 ASCII 字符,則必須確保資料在資料庫之間傳遞時保持正確編碼。資料庫和您的 Python 應用程式。
ODBC 解決方案
此代碼確保在傳送和檢索資料至資料庫時,使用 UTF-8 對字串資料進行編碼和解碼。 在處理非 ASCII 字元或確保與 Unicode 資料的兼容性時,這一點尤其重要。
def create_connection(connection_string, password): connection = None try: # print(f"Connecting to {connection_string}") connection = pyodbc.connect(connection_string + ";PWD=" + password) # Ensure strings are read correctly connection.setdecoding(pyodbc.SQL_CHAR, encoding="utf8") connection.setdecoding(pyodbc.SQL_WCHAR, encoding="utf8") connection.setencoding(encoding="utf8") except pyodbc.Error as e: print(f"The error '{e}' occurred") return connection
connection.setdecoding(pyodbc.SQL_CHAR,encoding="utf8")
告訴 pyodbc 在取得 SQL_CHAR 類型(通常是固定長度字元欄位)時如何從資料庫中解碼字元資料。
connection.setdecoding(pyodbc.SQL_WCHAR,encoding="utf8")
設定 SQL_WCHAR、寬字元類型(即 Unicode 字串,例如 SQL Server 中的 NVARCHAR 或 NCHAR)的解碼。
connection.setencoding(encoding="utf8")
確保從 Python 發送到資料庫的任何字串或字元資料都將使用 UTF-8 進行編碼,
這表示Python在與資料庫通訊時會將其內部str類型(即Unicode)轉換為UTF-8位元組。
把它們放在一起
安裝 JDBC
安裝JAVA - 使用dmg
https://www.oracle.com/middleeast/java/technologies/downloads/#jdk23-mac
更新 shell 以設定預設版本
$ /usr/libexec/java_home -V Matching Java Virtual Machines (2): 23 (arm64) "Oracle Corporation" - "Java SE 23" /Library/Java/JavaVirtualMachines/jdk-23.jdk/Contents/Home 1.8.421.09 (arm64) "Oracle Corporation" - "Java" /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home /Library/Java/JavaVirtualMachines/jdk-23.jdk/Contents/Home $ echo $SHELL /opt/homebrew/bin/bash $ vi ~/.bash_profile
將 JAVA_HOME 加入您的路徑
export JAVA_HOME=$(/usr/libexec/java_home -v 23) export PATH=$JAVA_HOME/bin:$PATH
取得 JDBC 驅動程式
https://intersystems-community.github.io/iris-driver-distribution/
將 jar 檔案放在某個地方...我把它放在 $HOME
$ ls $HOME/*.jar /Users/myname/intersystems-jdbc-3.8.4.jar
範例程式碼
它假設你已經設定了 ODBC(另一天的例子,狗吃了我的筆記...)。
注意:這是對我的真實程式碼的修改。請注意變數名稱。
import os import datetime from datetime import date, time, datetime, timedelta import pandas as pd import pyodbc import jaydebeapi import jpype def jdbc_create_connection(jdbc_url, jdbc_username, jdbc_password): # Path to JDBC driver jdbc_driver_path = '/Users/yourname/intersystems-jdbc-3.8.4.jar' # Ensure JAVA_HOME is set os.environ['JAVA_HOME']='/Library/Java/JavaVirtualMachines/jdk-23.jdk/Contents/Home' os.environ['CLASSPATH'] = jdbc_driver_path # Start the JVM (if not already running) if not jpype.isJVMStarted(): jpype.startJVM(jpype.getDefaultJVMPath(), classpath=[jdbc_driver_path]) # Connect to the database connection = None try: connection = jaydebeapi.connect("com.intersystems.jdbc.IRISDriver", jdbc_url, [jdbc_username, jdbc_password], jdbc_driver_path) print("Connection successful") except Exception as e: print(f"An error occurred: {e}") return connection def odbc_create_connection(connection_string): connection = None try: # print(f"Connecting to {connection_string}") connection = pyodbc.connect(connection_string) # Ensure strings are read correctly connection.setdecoding(pyodbc.SQL_CHAR, encoding="utf8") connection.setdecoding(pyodbc.SQL_WCHAR, encoding="utf8") connection.setencoding(encoding="utf8") except pyodbc.Error as e: print(f"The error '{e}' occurred") return connection # Parameters odbc_driver = "InterSystems ODBC" odbc_host = "your_host" odbc_port = "51773" odbc_namespace = "your_namespace" odbc_username = "username" odbc_password = "password" jdbc_host = "your_host" jdbc_port = "51773" jdbc_namespace = "your_namespace" jdbc_username = "username" jdbc_password = "password" # Create connection and create charts jdbc_used = True if jdbc_used: print("Using JDBC") jdbc_url = f"jdbc:IRIS://{jdbc_host}:{jdbc_port}/{jdbc_namespace}?useUnicode=true&characterEncoding=UTF-8" connection = jdbc_create_connection(jdbc_url, jdbc_username, jdbc_password) else: print("Using ODBC") connection_string = f"Driver={odbc_driver};Host={odbc_host};Port={odbc_port};Database={odbc_namespace};UID={odbc_username};PWD={odbc_password}" connection = odbc_create_connection(connection_string) if connection is None: print("Unable to connect to IRIS") exit() cursor = connection.cursor() site = "SAMPLE" table_name = "your.TableNAME" desired_columns = [ "RunDate", "ActiveUsersCount", "EpisodeCountEmergency", "EpisodeCountInpatient", "EpisodeCountOutpatient", "EpisodeCountTotal", "AppointmentCount", "PrintCountTotal", "site", ] # Construct the column selection part of the query column_selection = ", ".join(desired_columns) query_string = f"SELECT {column_selection} FROM {table_name} WHERE Site = '{site}'" print(query_string) cursor.execute(query_string) if jdbc_used: # Fetch the results results = [] for row in cursor.fetchall(): converted_row = [str(item) if isinstance(item, jpype.java.lang.String) else item for item in row] results.append(converted_row) # Get the column names and ensure they are Python strings (java.lang.String is returned "(p,a,i,n,i,n,t,h,e,a,r,s,e)" column_names = [str(col[0]) for col in cursor.description] # Create the dataframe df = pd.DataFrame.from_records(results, columns=column_names) print(df.head().to_string()) else: # For very large result sets get results in chunks using cursor.fetchmany(). or fetchall() results = cursor.fetchall() # Get the column names column_names = [column[0] for column in cursor.description] # Create the dataframe df = pd.DataFrame.from_records(results, columns=column_names) print(df.head().to_string()) # # Build charts for a site # cf.build_7_day_rolling_average_chart(site, cursor, jdbc_used) cursor.close() connection.close() # Shutdown the JVM (if you started it) # jpype.shutdownJVM()
以上是使用 Python 透過 ODBC 或 JDBC 存取 IRIS 資料庫的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Python更易學且易用,C 則更強大但複雜。 1.Python語法簡潔,適合初學者,動態類型和自動內存管理使其易用,但可能導致運行時錯誤。 2.C 提供低級控制和高級特性,適合高性能應用,但學習門檻高,需手動管理內存和類型安全。

要在有限的時間內最大化學習Python的效率,可以使用Python的datetime、time和schedule模塊。 1.datetime模塊用於記錄和規劃學習時間。 2.time模塊幫助設置學習和休息時間。 3.schedule模塊自動化安排每週學習任務。

Python在開發效率上優於C ,但C 在執行性能上更高。 1.Python的簡潔語法和豐富庫提高開發效率。 2.C 的編譯型特性和硬件控制提升執行性能。選擇時需根據項目需求權衡開發速度與執行效率。

每天學習Python兩個小時是否足夠?這取決於你的目標和學習方法。 1)制定清晰的學習計劃,2)選擇合適的學習資源和方法,3)動手實踐和復習鞏固,可以在這段時間內逐步掌握Python的基本知識和高級功能。

Python和C 各有優勢,選擇應基於項目需求。 1)Python適合快速開發和數據處理,因其簡潔語法和動態類型。 2)C 適用於高性能和系統編程,因其靜態類型和手動內存管理。

pythonlistsarepartofthestAndArdLibrary,herilearRaysarenot.listsarebuilt-In,多功能,和Rused ForStoringCollections,而EasaraySaraySaraySaraysaraySaraySaraysaraySaraysarrayModuleandleandleandlesscommonlyusedDduetolimitedFunctionalityFunctionalityFunctionality。

Python在自動化、腳本編寫和任務管理中表現出色。 1)自動化:通過標準庫如os、shutil實現文件備份。 2)腳本編寫:使用psutil庫監控系統資源。 3)任務管理:利用schedule庫調度任務。 Python的易用性和豐富庫支持使其在這些領域中成為首選工具。

Python在Web開發中的關鍵應用包括使用Django和Flask框架、API開發、數據分析與可視化、機器學習與AI、以及性能優化。 1.Django和Flask框架:Django適合快速開發複雜應用,Flask適用於小型或高度自定義項目。 2.API開發:使用Flask或DjangoRESTFramework構建RESTfulAPI。 3.數據分析與可視化:利用Python處理數據並通過Web界面展示。 4.機器學習與AI:Python用於構建智能Web應用。 5.性能優化:通過異步編程、緩存和代碼優
