我可以从 teradata 数据库中选择,但我不能使用 pyspark 删除。
我还使用 jaydebeapi 在同一个 spark 会话中删除了表,这很有效。 希望有人可能遇到过同样的问题。
drop_sql = """ (DROP TABLE <DB_NAME>.<TABLENAME>) """
conn = spark.read \
.format("jdbc") \
.option("driver","com.teradata.jdbc.TeraDriver") \
.option("url","jdbc:teradata://<IP_ADDRESS>/DATABASE=. <DB_NAME>,TMODE=ANSI,CHARSET=UTF8,TYPE=FASTLOAD,LOGMECH=LDAP") \
.option("query", drop_sql) \
.option("user", user) \
.option("password",password)\
.option("fetchsize",10000).load()
错误:
Py4JJavaError: 调用 o265.load 时出错。 : java.sql.SQLException: [Teradata Database] [TeraJDBC 17.20.00.15] [Error 3707] [SQLState 42000] 语法错误,需要类似名称或 Unicode 分隔标识符或“UDFCALLNAME”关键字或“SELECT”关键字或 '(' 在 '(' 和 'DROP' 关键字之间。
spark.read
提供更高级别的语言。它不是 python 的 Terradata 驱动程序。
spark.read.format('jdbc').option(query, '...')
的查询只能包含SELECT
语句。SELECT
中。例如
spark.read.format("jdbc") \
.option("url", jdbcUrl) \
.option("query", "SELECT c1, c2 FROM t1") \
.option("partitionColumn", "partiion_id") \
.option("lowerBound", "1") \
.option("upperBound", "100") \
.option("numPartitions", "3") \
.load()
将转化为 3 个类似的查询,这些查询在底层数据库上并行执行。请注意真实的会略有不同,这是为学术目的而策划的:
SELECT t.* FROM (SELECT c1, c2 FROM t1 WHERE partiion_id BETWEEN 1 AND 100) t
SELECT t.* FROM (SELECT c1, c2 FROM t1 WHERE partiion_id BETWEEN 100 AND 200) t
SELECT t.* FROM (SELECT c1, c2 FROM t1 WHERE partiion_id BETWEEN 100 AND 300) t
所以在你的情况下,Terradata 不开心,因为 Spark 正在执行以下内容:
SELECT t.* FROM (DROP TABLE <DB_NAME>.<TABLENAME>) t
你拥有的不是“pyspark jdbc connector to teradata”。它是“Terradata JDBC 驱动程序”。
要在 Terradata 上运行Terradata 特定的 SQL,您需要编写使用 Terradata 特定驱动程序的 python 代码。 这是一个例子.
import teradatasql
with teradatasql.connect (host="whomooz", user="guest", password="please") as con:
with con.cursor () as cur:
with con.cursor () as cur2:
try:
sRequest = "DROP TABLE <DB_NAME>.<TABLENAME>"
print (sRequest)
cur.execute (sRequest)
except Exception as ex:
print ("Ignoring", str (ex).split ("\n") [0])
如果您想在 Databricks/Spark-cluster 上运行此代码,则必须在相关集群上添加 jdbc 驱动程序库。例如。作为 集群库。然后在该集群上运行上面的代码。
鉴于您遇到的错误,我假设您已经完成了此操作。