![](/img/trans.png)
[英]Failing to create table using bound parameters in sqlalchemy/cx_oracle
[英]Select TIMESTAMP(6) WITH TIME ZONE using Pandas, SQLAlchemy and cx_Oracle
我正在嘗試使用 pandas 到 select 來自 Oracle 數據庫的一些數據。 相關列的數據類型為TIMESTAMP(6) WITH TIME ZONE
。 我與數據庫處於同一時區,但它包含從不同時區記錄的數據。
Oracle version: Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
Python 3.8.13
SQLAlchemy 1.4.39
cx_Oracle 8.3.0
在 PL/SQL Developer 中,查詢有效:
SELECT col
FROM table
退貨
18-JAN-21 09.54.58.000000000 PM ASIA/BANGKOK
在 Python 中,我收到此錯誤:
import sqlalchemy
import cx_Oracle
server = server
port = port
sid = sid
username = username
password = password
dsn_tns = cx_Oracle.makedsn(server, port, sid)
cnxn = cx_oracle.connect(username, password, dsn_tns)
query = """
SELECT col
FROM table
"""
df = pd.read_sql_query(query, cnxn)
Output:
DatabaseError: ORA-01805: possible error in date/time operation
經過一些 SO 搜索,我嘗試了這個:
query = """
SELECT CAST(TO_TIMESTAMP_TZ(
col,
'DD-MMM-YY HH.MI.SS.FF6 TZH TZR')
) AT TIME ZONE 'ASIA/BANGKOK' AS col
FROM table
"""
df = pd.read_sql_query(query, cnxn_tds_dev)
它返回不同的錯誤消息:
ORA-00905: missing keyword
我怎樣才能使用 Python/SQLAlchemy/cx_Oracle 僅 select 這個時間戳列(以及其他幾個)? 因為查詢在 PL/SQL Developer 中有效,所以我假設這是 cx_Oracle 的問題。 根據這篇文章,我將嘗試使用舊版本的 cx_Oracle 創建一個新的 Python 環境。
作為記錄,我在原始評論線程中提到的代碼是:
# create table t (c TIMESTAMP(6) WITH TIME ZONE);
# insert into t (c) values (systimestamp);
# commit;
#
# Name: pandas
# Version: 1.5.2
# Name: SQLAlchemy
# Version: 1.4.44
# Name: cx-Oracle
# Version: 8.3.0
#
# Output is like:
# 0 2022-11-24 11:49:25.505773
import os
import platform
from sqlalchemy import create_engine
import pandas as pd
import cx_Oracle
if platform.system() == "Darwin":
cx_Oracle.init_oracle_client(lib_dir=os.environ.get("HOME")+"/Downloads/instantclient_19_8")
username = os.environ.get("PYTHON_USERNAME")
password = os.environ.get("PYTHON_PASSWORD")
connect_string = os.environ.get("PYTHON_CONNECTSTRING")
hostname, service_name = connect_string.split("/")
engine = create_engine(f'oracle://{username}:{password}@{hostname}/?service_name={service_name}')
query = """select * from t"""
df = pd.read_sql_query(query, engine)
print(df)
一種解決方案是將有問題的列轉換為字符串,然后轉換為 pandas。
query = "SELECT TO_CHAR(col) AS col FROM table"
df = pd.read_sql_query(query, cnxn)
df[col] = df[col].apply(pd.to_datetime, format="%d-%b-%y %I.%M.%S.%f %p %Z")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.