Case Conventions in Python, JavaScript and SQL Server
The cases themselves are just word-separator rules — how a multi-word name like user account id gets squashed into a single valid identifier. The convention a language uses on top of that is a separate, mostly arbitrary choice, which is why the same concept (a variable, a class, a constant) can look completely different depending on which of the three you’re writing.
The cases
| Case | Example | Separator |
|---|---|---|
snake_case | user_account_id | underscore, all lowercase |
SCREAMING_SNAKE_CASE | MAX_RETRY_COUNT | underscore, all uppercase |
camelCase | userAccountId | none — capitalize each word after the first |
PascalCase | UserAccountId | none — capitalize every word, including the first |
kebab-case | user-account-id | hyphen, all lowercase |
kebab-case is unusual in that almost no programming language accepts a hyphen inside an identifier — user-account-id as a variable name parses as user MINUS account MINUS id. It survives mainly in places that were never identifiers to begin with: URLs, filenames, CSS class names, npm package names, CLI flags (--dry-run).
Python
Python’s own style guide, PEP 8, is unusually explicit about this and most Python code follows it closely:
| What | Convention | Example |
|---|---|---|
| Variables, functions | snake_case | def get_user_by_id(): |
| Modules, packages | snake_case | import json_schema_to_zod |
| Classes, exceptions | PascalCase | class UserAccount: |
| Constants | SCREAMING_SNAKE_CASE | MAX_RETRY_COUNT = 5 |
| “Private” attributes | leading underscore | self._cache, def _helper(): |
| Name-mangled attributes | leading double underscore | self.__internal_state |
The single case that trips people up coming from JavaScript is that Python functions and variables are snake_case, not camelCase — getUserById is valid Python but reads as foreign the moment anyone familiar with PEP 8 sees it.
JavaScript / TypeScript
JavaScript has no single official style guide — Airbnb’s and Google’s are the two most widely adopted — but the conventions below are close to universal regardless of which one a project follows:
| What | Convention | Example |
|---|---|---|
| Variables, functions | camelCase | function getUserById() {} |
| Classes, React/Vue components, TS types & interfaces | PascalCase | class UserAccount {}, <UserCard />, type UserAccount = {...} |
| Constants (module-level, truly immutable) | SCREAMING_SNAKE_CASE | const MAX_RETRY_COUNT = 5; |
| “Private” class fields | leading underscore (convention) or # (real private, ES2022+) | this._cache, #internalState |
| Filenames | mixed — kebab-case or camelCase for modules, PascalCase for component files | sql-format.ts, SqlFormatter.astro |
The SCREAMING_SNAKE_CASE constant convention is weaker in JavaScript than in Python — it’s generally reserved for true global constants (MAX_RETRIES, enum-like objects) rather than every const declaration, since const in JS just means “not reassigned,” not “immutable value.”
SQL Server
SQL Server identifiers are case-insensitive by default (the server’s default collation is almost always case-insensitive, so UserAccount and useraccount refer to the same object) which is exactly why a written convention matters more here, not less — nothing in the engine enforces it, so drift is silent. Two conventions dominate in practice, and which one a codebase uses is usually just inherited from whichever ORM or team wrote the original schema:
| What | Convention | Example |
|---|---|---|
| Tables, views, columns (T-SQL / Microsoft house style) | PascalCase | CREATE TABLE UserAccount (AccountId INT, CreatedDate DATETIME2) |
| Tables, views, columns (portable/Postgres-influenced style) | snake_case | CREATE TABLE user_account (account_id INT, created_date DATETIME2) |
| Stored procedures | PascalCase, often prefixed | usp_GetUserById, spGetUserById |
| Variables (T-SQL script) | camelCase or PascalCase, always @-prefixed | DECLARE @userId INT; |
| Temp tables | # prefix, otherwise same as tables | #TempUserAccount |
Two things worth knowing before writing a WHERE clause against an unfamiliar schema: because identifiers are case-insensitive, a query written against UserAccount still matches a table physically named useraccount; but string data inside columns is compared using the column’s collation, which is usually case-insensitive too (CI in the collation name) but isn’t guaranteed — a CS (case-sensitive) collation means WHERE Email = '[email protected]' won’t match a stored '[email protected]'. See SQL Server: Schema Discovery Without Admin Access for how to check a column’s actual datatype and collation before relying on either assumption.
Cross-language quick reference
The same logical name, as it would actually appear in each context:
| Concept | Python | JavaScript | SQL Server (PascalCase house style) |
|---|---|---|---|
| a variable | user_id | userId | @userId (T-SQL variable) |
| a function/procedure | get_user_by_id | getUserById | usp_GetUserById |
| a class/table | UserAccount | UserAccount | UserAccount |
| a constant | MAX_RETRIES | MAX_RETRIES | n/a — no constant concept in T-SQL |