Attributes are the building blocks of the HoneyEQL queries. During initialization, HoneyEQL reads the database metadata and creates attributes (generation phase) of each columns and relationships in the database. Then while querying, it uses these attributes to create the appropriate SQL query (resolution phase).
This section documents the convention behind the naming of attributes in the generation phase.
HoneyEQL uses the terminology entity to represent a table & attribute to represent either a column or a relationship.
The attributes that are referring a column are called as column attributes and ones that represent a relationship are called as join attributes.
An attribute is represented using Clojure's namespaced keyword.
:{table-name-in-kebab-case}/{column-or-relationship-name-in-kebab-case}
An attributes namespace namespace is the singularized, kebab-case version of the corresponding table or view name.
| Table/View Name | Attribute Namespace |
|---|---|
| actor | actor |
| film_actor | film-actor |
| comments | comment |
HoneyEQL supports Postgres schema. If the schema in question is not a default schema (public), then it will be used as a prefix in the Attribute namespace.
| Schema Name | Table/View Name | Attribute namespace |
|---|---|---|
| person | state_province | person.state-province |
| human_resources | employee | human-resources.employee |
NOTE: The table name is alone singularized and not the schema name.
The actual keyword part of an attribute refers to the column name in kebab-case.
| Schema Name | Table/View Name | Column Name | Attribute |
|---|---|---|---|
| public | actor | first_name | :actor/first-name |
| public | film_actor | actor_id | :film-actor/actor-id |
| public | comments | authorId | :comment/author-id |
| person | state_province | name | :person.state-province/name |
| human_resources | employee | id | :human-resources.employee/id |
NOTE: MySQL doesn't support schema.
HoneyEQL identifies the relationships between database tables using their foreign keys, and generate appropriate join (relationship) attributes.

For the database table relationships like above, HoneyEQL infers two one-to-many relationships.
A city has many address (addresses) via city_id column in the address table.
A country has many city (cities) via country_id column in the city table.
HoneyEQL then generate two join attributes.
:city/addresses
:country/cities
The generated field name is the kebab-case version of the corresponding target table's pluralized name.
If a table has multiple foreign keys to the same table as below,
CREATE TABLE language (
language_id serial PRIMARY KEY,
name character(20) NOT NULL
);
CREATE TABLE film (
film_id serial PRIMARY KEY,
title character varying(255) NOT NULL,
language_id smallint NOT NULL REFERENCES language(language_id),
original_language_id smallint REFERENCES language(language_id)
);
HoneyEQL creates two one-to-many join attributes to represent these relationship between language and films.
language has many film (films) via language_id column in the film table.language has many film (films) via original_language_id column in the film table.:language/films
:language/original-language-films
The nomenclature used here to generate the field name follows the below logic.
If the column name (language_id) after the removal of the foreign key suffix (language) matches the source table name, then the resulting field name is the kebab-case version of the pluralized form of the target table (films).
If the column name (original_language_id) after the removal of the foreign key suffix (original_language) did not match the source table name, then HoneyEQL removes the foreign key suffix and concatenate with the pluralized form of the target table and then convert it to its kebab-case version (original-language-films).

For the database table relationships like above, HoneyEQL infers two one-to-one relationships.
An address is associated with a city via city_id column in the address table.
A city is associated with a country via country_id column in the city table.
In this scenario, HoneyEQL generates two attributes representing these two relationships.
:address/city
:city/country
The generated attribute keyword is the kebab-case version of the corresponding column name with the id suffix (_id) removed.
Here are some of the examples.
| Table/View Name | Column Name | Attribute |
|---|---|---|
| film_actor | actor_id | :film-actor/actor |
| film | original_language_id | :film/originalLanguage |
| employee | reports_to_employee_id | :employee/reportsToEmployee |
By default, HoneyEQL assumes _id as the suffix for foreign keys in both Postgres and MySQL.
In future, HoneyEQL will provide a configuration to override this default behavior.
HoneyEQL infers one to one relationship if the primary key and a foreign key of a table are same.

For the above DB schema, HoneyEQL infers two one-to-one relationships.
site is associated with a site-meta-dataum via site_id column in the site-meta-dataum table.site-meta-dataum is associated with a site via site_id column in the site-meta-dataum table.For this example, HoneyEQL generates two attributes
:site/site-meta-datum
:site-meta-datum/site
The many-to-many relationship is a bit tricky to figure out.
HoneyEQL traverses each table's metadata to figure out whether it is an associative table or not.
A table is considered as an associative table if it satisfies the following two criteria
For the database table relationships like below,

The film_actor table is an associative table as
actor_id and film_id as the primary keys.{actor_id, film_id} is a subset of foreign keys {actor_id, film_id} of the film_actor table.In this scenario, HoneyEQL creates two join attributes for these two many-to-many relationships.
:film/actors
:actor/films
For the relationships between film & film_actor and film_actor & actor tables, HoneyEQL generates the following attributes.
; one to many
:film/film-actors
; one to one
:film-actor/film
:film-actor/actor
; one to many
:actor/film-actors
If the foreign key in question doesn't have the id suffix _id, then the HoneyEQL follows a slightly different approach to name the attributes.
Say, we have a below schema
CREATE TABLE continent (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE country (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
continent_identifier int REFERENCES continent(id)
);
The continent_identifier column doesn't have the foreign key suffix (_id).
For the one-to-one relationship, HoneyEQL creates a field with the name continentByContinentIdentifer.
The convention is {targetTableNameInKebabCase}-by-{FKeyColumnNameInKebabCase}.
:country/continent-by-continent-identifier
On the one-to-many side, the attribute is the concatenation of the kebab-case version of the foreign key column name (continent-identifer) with the pluralized form of the target table (countries).
:continent/continent-identifer-countries
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |