FAQ

General

What is CQL?

CQL (Crystal Query Language) is an ORM (Object-Relational Mapping) library for Crystal that provides type-safe database interactions, migrations, and Active Record patterns.

What databases does CQL support?

CQL supports:

  • PostgreSQL

  • MySQL

  • SQLite

Is CQL production-ready?

CQL is actively maintained and used in production applications. However, as with any library, thoroughly test your specific use case.

Models

Should I use class or struct for models?

Both work with CQL. Use struct for value semantics (recommended for most cases) or class if you need reference semantics.

Why is my primary key nullable?

Primary keys should be Type? (nullable) because new records don't have an ID until saved:

How do I add a field that isn't in the database?

Use the DB::Field(ignore: true) annotation:

Queries

How do I write raw SQL?

Why is my query returning an empty array?

Check:

  1. Data exists in the database

  2. Your where conditions are correct

  3. If using soft deletes, records might be deleted

How do I debug what SQL is being generated?

Enable query logging:

Relationships

When do I use belongs_to vs has_many?

  • belongs_to: The model has a foreign key column (e.g., Comment has post_id)

  • has_many: The other model has the foreign key (e.g., Post has many Comments)

How do I eager load associations?

Load related IDs first, then batch load:

Migrations

How do I add a column to an existing table?

How do I rollback a migration?

What if a migration fails halfway through?

Manually check the database state, fix any issues, and potentially mark the migration as not applied:

Performance

How do I avoid N+1 queries?

Load related data in batches:

Should I add indexes?

Add indexes on:

  • Foreign key columns

  • Columns used in WHERE clauses

  • Columns used in ORDER BY

Troubleshooting

"Connection refused" error

The database server isn't running or the connection string is wrong. Check:

  1. Database is running: pg_isready or mysqladmin ping

  2. Connection string is correct

"Table does not exist" error

Migrations haven't run. Execute:

"Validation failed" but I don't know why

Check the errors array:

Best Practices

Should I use save or save!?

  • Use save when you want to handle failure gracefully

  • Use save! when failure should raise an exception

When should I use transactions?

When multiple operations must succeed or fail together:

How do I test my models?

Use a test database and reset it between tests:

Last updated

Was this helpful?