Python SQLAlchemy PostgreSQL SyntaxError for table with multiple hyphens in the name

Question:

I have a table name users-activity-data in the schema named public. When I try to query the table using pandas.read_sql:

engine = sqlalchemy.create_engine(conn)
pd.read_sql("""select * from public.users-activity-data""", engine)

I am getting psycopg2.errors.SyntaxError at or near "-".

I cannot change the table name and have tried using [] and “ around the table name as well, but I am getting the same error. Also, it’s working fine for other tables in the schema that do not have a hyphen in the name.

Asked By: Abhishek Agarwal

||

Answers:

create table users-activity-data (id int);
ERROR:  syntax error at or near "-"
LINE 1: create table users-activity-data (id int);

create table "users-activity-data" (id int);
CREATE TABLE

import psycopg2

con = psycopg2.connect(dbname="test", host='localhost', user='postgres', port=5432)
cur = con.cursor()

cur.execute("""select * from public.users-activity-data""")
SyntaxError: syntax error at or near "-"
LINE 1: select * from public.users-activity-data

con.rollback()
cur.execute('select * from public."users-activity-data"')

Per Identifiers:

SQL identifiers and key words must begin with a letter (a-z, but also letters with diacritical marks and non-Latin letters) or an underscore (_). Subsequent characters in an identifier or key word can be letters, underscores, digits (0-9), or dollar signs ($). Note that dollar signs are not allowed in identifiers according to the letter of the SQL standard, so their use might render applications less portable. The SQL standard will not define a key word that contains digits or starts or ends with an underscore, so identifiers of this form are safe against possible conflict with future extensions of the standard.

There is a second kind of identifier: the delimited identifier or quoted identifier. It is formed by enclosing an arbitrary sequence of characters in double-quotes ("). A delimited identifier is always an identifier, never a key word. So "select" could be used to refer to a column or table named “select”, whereas an unquoted select would be taken as a key word and would therefore provoke a parse error when used where a table or column name is expected. The example can be written with quoted identifiers like this:

UPDATE "my_table" SET "a" = 5;

Quoted identifiers can contain any character, except the character with code zero. (To include a double quote, write two double quotes.) This allows constructing table or column names that would otherwise not be possible, such as ones containing spaces or ampersands. The length limitation still applies.

Answered By: Adrian Klaver
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.