Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Teradata "CTAS" error - BT/ET is not closed properly #35

Open
pkasinathan opened this issue Dec 19, 2017 · 3 comments
Open

Teradata "CTAS" error - BT/ET is not closed properly #35

pkasinathan opened this issue Dec 19, 2017 · 3 comments

Comments

@pkasinathan
Copy link

pkasinathan commented Dec 19, 2017

Hi Team,

ct syntax to create table on sqlachemy-teradata is not working as expected.

When I run ct pp_scratch.temp_pxk as (select username from dbc.usersV) with data;, it's getting successfully executed. But, when I run some select sql, its throwing error [Teradata][ODBC Teradata Driver][Teradata Database] Only an ET or null statement is legal after a DDL Statement. ')

When I deep dive, I found that it's adding BT before running the ct statement, but it's not adding ET after the statement execution. It's a DDL statement, so I expect ET would have been added implicitly, but not.

Create Table, Drop Table are all working. The problem is with ct syntax.

For more details, I attached the Jupyter notebook to provide more information.

Please let me know how to solve this issue.

How to reproduce this error?
sqlalchemy_teradata_ctas_error.pdf

export LD_LIBRARY_PATH=/opt/teradata/client/14.10/odbc_64/lib64:/opt/teradata/client/14.10/odbc_64/lib:/usr/lib:$LD_LIBRARY_PATH:

export ODBCINI=/opt/teradata/odbc.ini

[10:59]:[root@lvshdcjupy001:~]# ipython
Python 3.5.2 |Anaconda 4.1.1 (64-bit)| (default, Jul  2 2016, 17:53:06) 
IPython 4.2.0 -- An enhanced Interactive Python.

In [1]: from sqlalchemy import create_engine

In [2]: td_engine1 = create_engine('teradata://myuser:mypass@teradata_system:22/')

In [3]: result = td_engine1.execute("ct mydb.temp as (select username from dbc.usersV) with data")

In [4]: result = td_engine1.execute("select * from mydb.temp")
---------------------------------------------------------------------------
DatabaseError                             Traceback (most recent call last)
/opt/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py in _execute_context(self, dialect, constructor, statement, parameters, *args)
   1138                         parameters,
-> 1139                         context)
   1140         except Exception as e:

/opt/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/default.py in do_execute(self, cursor, statement, parameters, context)
    449     def do_execute(self, cursor, statement, parameters, context=None):
--> 450         cursor.execute(statement, parameters)
    451 

/opt/anaconda3/lib/python3.5/site-packages/teradata/tdodbc.py in execute(self, query, params, queryTimeout)
    591                 self.hStmt, _inputStr(_convertLineFeeds(query)), SQL_NTS)
--> 592             checkStatus(rc, hStmt=self.hStmt, method="SQLExecDirectW")
    593         self._handleResults()

/opt/anaconda3/lib/python3.5/site-packages/teradata/tdodbc.py in checkStatus(rc, hEnv, hDbc, hStmt, method, ignore)
    208                                  "variables are correctly set.")
--> 209                 raise DatabaseError(i[2], u"[{}] {}".format(i[0], msg), i[0])
    210             else:

DatabaseError: (3807, "[42S02] [Teradata][ODBC Teradata Driver][Teradata Database] Object 'mydb.temp' does not exist. ")

The above exception was the direct cause of the following exception:

DatabaseError                             Traceback (most recent call last)
<ipython-input-4-b93a630e7bf3> in <module>()
----> 1 result = td_engine1.execute("select * from mydb.temp")

/opt/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py in execute(self, statement, *multiparams, **params)
   1989 
   1990         connection = self.contextual_connect(close_with_result=True)
-> 1991         return connection.execute(statement, *multiparams, **params)
   1992 
   1993     def scalar(self, statement, *multiparams, **params):

/opt/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py in execute(self, object, *multiparams, **params)
    904         """
    905         if isinstance(object, util.string_types[0]):
--> 906             return self._execute_text(object, multiparams, params)
    907         try:
    908             meth = object._execute_on_connection

/opt/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py in _execute_text(self, statement, multiparams, params)
   1052             statement,
   1053             parameters,
-> 1054             statement, parameters
   1055         )
   1056         if self._has_events or self.engine._has_events:

/opt/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py in _execute_context(self, dialect, constructor, statement, parameters, *args)
   1144                 parameters,
   1145                 cursor,
-> 1146                 context)
   1147 
   1148         if self._has_events or self.engine._has_events:

/opt/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py in _handle_dbapi_exception(self, e, statement, parameters, cursor, context)
   1339                 util.raise_from_cause(
   1340                     sqlalchemy_exception,
-> 1341                     exc_info
   1342                 )
   1343             else:

/opt/anaconda3/lib/python3.5/site-packages/sqlalchemy/util/compat.py in raise_from_cause(exception, exc_info)
    200     exc_type, exc_value, exc_tb = exc_info
    201     cause = exc_value if exc_value is not exception else None
--> 202     reraise(type(exception), exception, tb=exc_tb, cause=cause)
    203 
    204 if py3k:

/opt/anaconda3/lib/python3.5/site-packages/sqlalchemy/util/compat.py in reraise(tp, value, tb, cause)
    183             value.__cause__ = cause
    184         if value.__traceback__ is not tb:
--> 185             raise value.with_traceback(tb)
    186         raise value
    187 

/opt/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/base.py in _execute_context(self, dialect, constructor, statement, parameters, *args)
   1137                         statement,
   1138                         parameters,
-> 1139                         context)
   1140         except Exception as e:
   1141             self._handle_dbapi_exception(

/opt/anaconda3/lib/python3.5/site-packages/sqlalchemy/engine/default.py in do_execute(self, cursor, statement, parameters, context)
    448 
    449     def do_execute(self, cursor, statement, parameters, context=None):
--> 450         cursor.execute(statement, parameters)
    451 
    452     def do_execute_no_params(self, cursor, statement, context=None):

/opt/anaconda3/lib/python3.5/site-packages/teradata/tdodbc.py in execute(self, query, params, queryTimeout)
    590             rc = odbc.SQLExecDirectW(
    591                 self.hStmt, _inputStr(_convertLineFeeds(query)), SQL_NTS)
--> 592             checkStatus(rc, hStmt=self.hStmt, method="SQLExecDirectW")
    593         self._handleResults()
    594         return self

/opt/anaconda3/lib/python3.5/site-packages/teradata/tdodbc.py in checkStatus(rc, hEnv, hDbc, hStmt, method, ignore)
    207                                  "and the ODBCINI or ODBCINST environment "
    208                                  "variables are correctly set.")
--> 209                 raise DatabaseError(i[2], u"[{}] {}".format(i[0], msg), i[0])
    210             else:
    211                 logger.debug(

DatabaseError: (teradata.api.DatabaseError) (3807, "[42S02] [Teradata][ODBC Teradata Driver][Teradata Database] Object 'mydb.temp' does not exist. ") [SQL: 'select * from mydb.temp']

In [5]: quit()
@pkasinathan
Copy link
Author

We are getting similar error after “Collect Stats” query too. Please help to fix.

@sandan
Copy link
Member

sandan commented Mar 23, 2018

@prabhu1984 Have you found a solution? The problem is that you are not committing the previous query. See http://docs.sqlalchemy.org/en/latest/core/connections.html#understanding-autocommit.

@alexisrolland
Copy link

alexisrolland commented Jul 3, 2018

I confirm that I face the same error with Collect Stats.
I have a script which:

  • Executes a create table statement
  • Executes a session commit
  • Executes a collect stats statement

it fails with error:

sqlalchemy.exc.DatabaseError: (teradata.api.DatabaseError) (3932, '[25000] [Teradata][ODBC Teradata Driver][Teradata Database] Only an ET or null statement is legal after a DDL Statement. ')

It's like the commit statement is not taken into account.
Here is the connection string I am using:

# Connect
self.engine = create_engine('teradata://' + self.user + ':' + self.password + '@' + self.host + ':22/' + self.database)
self.db_session = scoped_session(sessionmaker(autocommit=False, bind=self.engine))
self.db_session.execute('SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;')  # To avoid locking tables when doing select on tables
self.db_session.commit()

And here is the piece of code which executes both create table and collect stats statements:

def execute_sql_statement(self, query):
    """Generic method to execute a SQL statement on target environment."""
    query_list = sorted(query.keys())  # Sort dictionary key, in particular to execute table_stats query after table query
    for query_name in query_list:
        # Sanitize SQL to avoid parameter binding by SQLAlchemy
        sql_string = text(query[query_name].replace(':', '\:'))
        self.target_environment.db_session.execute(sql_string)
        self.target_environment.db_session.commit()
    return True

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants