Snowflake-Labs / django-snowflake

MIT License
59 stars 15 forks source link

Switch to using upper case identifiers (table names, column names, etc.) #35

Closed timgraham closed 2 years ago

timgraham commented 2 years ago

The current implementation of DatabaseOperations.quote_name() adds quotes around all identifiers like table and column names. This makes Snowflake treat the names case-sensitively, and Django uses lower case identifiers unless otherwise specified.

Using lower case names has some disadvantages, namely that quotes are subsequently always required around the identifires, otherwise, Snowflake will look for upper case names. One area this came up is in the raw SQL queries in Django's tests that don't include quotes. These have been skipped for now.

Cedar has a use case where table names are synced from PostgreSQL, apparently without quotes, so all these table names are treated as uppercase in Snowflake. To accommodate this use case and avoid the requirement of quotes in raw SQL, it might be best to adopt a similar approach as the Oracle backend, which has quote_name() uppercase all identifiers. (This would be a breaking change for anyone who has used django-snowflake 3.2 alpha 1 to create their tables and thus has lowercased names, but since the package is at alpha stage, backward compatibility isn't critical.)

Another solution to accommodate Cedar's use case could be to add an option to make DatabaseWrapper.init_connection_state() make the query: ALTER SESSION SET QUOTED_IDENTIFIERS_IGNORE_CASE = true.

timgraham commented 2 years ago

It seems that using QUOTED_IDENTIFIERS_IGNORE_CASE won't work because Snowflake generates constraint names that contain lower case letters, e.g. SYS_CONSTRAINT_08edbfe1-ae43-42d6-abff-4c028a042594.

I'm implementing the first proposal.

chrislondon commented 2 years ago

My current workaround is to add a db_column= param to my field declarations that include the uppercase name:

birthday = models.DateField(db_column="BIRTHDAY")