{"id":28962871,"url":"https://github.com/certainlach/immigrant","last_synced_at":"2025-06-24T03:12:26.334Z","repository":{"id":188648359,"uuid":"658987970","full_name":"CertainLach/immigrant","owner":"CertainLach","description":"Database schema definition language, migration and ORM boilerplate generator","archived":false,"fork":false,"pushed_at":"2025-06-06T15:40:48.000Z","size":585,"stargazers_count":9,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-20T04:24:35.989Z","etag":null,"topics":["database","migration","postgresql","schema","sql"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CertainLach.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-06-26T23:30:19.000Z","updated_at":"2025-06-06T15:40:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"8d660976-23da-4bc1-80be-f9720ae33a10","html_url":"https://github.com/CertainLach/immigrant","commit_stats":{"total_commits":98,"total_committers":1,"mean_commits":98.0,"dds":0.0,"last_synced_commit":"5b074e5cb02e104c3c80ab356f93a6d53813a41a"},"previous_names":["certainlach/immigrant"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/CertainLach/immigrant","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CertainLach%2Fimmigrant","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CertainLach%2Fimmigrant/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CertainLach%2Fimmigrant/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CertainLach%2Fimmigrant/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CertainLach","download_url":"https://codeload.github.com/CertainLach/immigrant/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CertainLach%2Fimmigrant/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261595786,"owners_count":23182250,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","migration","postgresql","schema","sql"],"created_at":"2025-06-24T03:12:25.492Z","updated_at":"2025-06-24T03:12:26.307Z","avatar_url":"https://github.com/CertainLach.png","language":"Rust","readme":"= immigrant\n\n++++\n\u003cp align=\"center\"\u003e\u003ca href=\"https://github.com/CertainLach/immigrant\"\u003e\u003cimg alt=\"immigrant temporary logo generated with midjourney\" src=\"./docs/pjotr.webp\" width=\"200px\"\u003e\u003c/img\u003e\u003c/a\u003e\u003c/p\u003e\n++++\n\nAn database schema definition language.\n\n== Example\n\nEveryone loves examples, here it is (github doesn't support immigrant code hightlighting yet):\n[source,plaintext]\n----\n/// You can define scalars, which are translated to PgSQL DOMAIN:\nscalar u31 = \"INTEGER\" @check \"u31_is_unsigned\" (_ \u003e= 0);\n/// Or you can create normal type aliases, which will be used in tables as-is,\n/// the same way as everyone writes SQL. This is more idiomatic in immigrant to use non-inlined scalars,\n/// as immigrant schemas in the wild are much more constrained than the normal SQL databases.\nscalar non_zero_int = \"INTEGER\" @check \"non_zero_int_cant_be_zero\" (_ != 0) @inline;\n\n/// You can also specify some of the column annotations on scalars.\n/// I.e if you want all of your data to be serchable by user, you can specify index on the user id type itself.\nscalar user_id = \"INTEGER\" @index;\n\n/// Or enums, which are less useful with better @checks, yet still have some useful features:\nenum user_group {\n\t/// Almost everywhere you can specify both schema name, and the database name.\n\t/// I.e if you had superuser group, and then decided to rename it to admin, you don't necessary\n\t/// need to change it in the database, you can specify its code name in the schema.\n\t/// You can also rename it btw, if you change the database name in the schema, immigrant will reconcile\n\t/// it in the database.\n\tadmin \"superuser\";\n\tnormal;\n};\n\n/// You can also define structs, which are translated to PgSQL COMPOSITE TYPE:\nstruct test_struct {\n\t/// Even if used database engine doesn't support struct checks, immigrant generators should try\n\t/// to support some set of common features as much as possible.\n\ta: u31 @check \"extra_checks\" (_ != 99);\n\t/// Checks with the same name are merged to ease ON CONFLICT ON CONSTRAINT creation.\n\tb: non_zero_int @check \"extra_checks\" (_ != 99);\n\t/// Immigrant includes some syntax sugar to specify constraints on per-item basis, same\n\t/// as sql allows to specify CHECKs on the columns.\n\t@check \"if_a_then_b\" (if _.a \u003e 10 then _.b \u003e 10 else true);\n};\n\n/// And of course, you can create tables too.\n/// Note the naming: In immigrant it is idiomatic to name things like in the code, and then either use\n/// naming convention preprocessor (i.e postgres naming convention will automatically name this table as \"users\"),\n/// or manually define table name, as any other database name in immigrant:\ntable User \"clients\" {\n\t/// In SQL you can omit some things, such as foreign key targets...\n\t/// In immigrant you can omit the field type, and it will pick type with the same name as the column.\n\tuser_id @primary_key;\n\tuser_group;\n\n\ttest_struct;\n};\n\ntable Post \"news\" {\n\tid: u31 @primary_key;\n\tuser_id ~ User;\n};\n----\n\n== Goals\n\nBe an extensible database schema modelling language:: Immigrant is designed to be highly extensible. It allows external\ntools to provide their own functionality and create code generators based on the immigrant database schema language.\nThis extensibility makes it a versatile tool that can be adapted to meet a variety of needs.\nProvide support for modern, and well-established database features:: Immigrant aims to provide robust support for a wide\nrange of database features. Every type, function, and database extension should be possible to use within the immigrant\nschema. Discouraged and deprecated database features should not be supported.\n[[readable-goal]]Generated migrations should be readable and easy to understand:: One of the guiding principles of\nimmigrant is that the migrations it generates should be easily readable and understandable. There should be no arcane\nmagic here; the logic behind migration decisions should be obvious to anyone reviewing the code.\n[[types-goal]]Provide more complete support for custom types, and make it easier to implement more validity checks::\nMost of the databases enforce users to perform checks on the application side, by i.e implementing only support for\nsigned integers. Immigrant has support for user-defined scalars, allowing to reuse logic more easily, encouraging users\nto have more checks on the database level, and allowing codegenerators to provide better support for newtype wrapping of\ndatabase primitives.\n[[autonomous-goal]]Be autonomous, work only on the defined schema, do not require the database connection:: Database\nconnection requirements complicates local development and the CI a lot, immigrant should operate strictly on what user\nhas defined in their schema definitions.\n\n== Non-goals\nAbstract SQL away:: While immigrant makes it easier to manage database schemas, it is not designed to completely\nabstract away SQL. Users should still be able to understand and write the generated migrations themselves. However,\nthey can also take advantage of the tool to automate some of this work.\nBe an ORM (Object-Relational Mapping):: While users of immigrant may implement their own code generators based on the\nschema, immigrant itself does not provide any tools to implement ORM functionality. It is a tool specifically designed\nfor managing database schemas, not for acting as a bridge between databases and objects in code.\nVersion control system integrations:: The default immigrant Command-Line Interface (CLI) implements an opinionated\nfile-based schema change management system. This should be sufficient for most users, but those who wish to integrate\nimmigrant with a version control system will need to implement their own solutions.\n[[generic-nongoal]]Provide the support for most SQL databases/generic database driver:: This non-goal conflicts with\n\u003c\u003creadable-goal,readability goal\u003e\u003e, as some things are implemented very differently in some databases. In sqlite, you\ncan only add/alter constraints using dropping and re-creating the table, and this will be messy to integrate into other\ndatabase migration codegenerators. Mixed driver codebases will only be implemented for databases that promise some level\nof compatibility, like PostgreSQL and CockroachDB, which should support the majority of common functionality.\nIntrospection-based schema generation:: This type of operation may be supported in initial database import, however it\nmay not work correctly, as some of the immigrant features may not be directly convertible from SQL.\n\n== Inspiration\n\nhttps://prisma.io[Prisma]:: I have learned about prisma after I have started implementing immigrant, however, my\ndesign decisions may be affected by Prisma. The things I dislike about prisma, is the implementation of\n\u003c\u003cgeneric-nongoal,generic database migration generator\u003e\u003e. While this feature may sound like a good idea, in fact this\nthing complicates the implementation a lot, preventing them from implementing some of the good features (such as views)\nin a timely manner. In case of sqlite migration layer, this thing skips most of the sql code generation due to complex\nconditions, and sqlite implementation only performs the basic operations. In immigrant, this should be the short sqlite\ndriver, which doesn't implement logic only required for more complete database solutions.\nhttps://github.com/zombodb/pg-schema-diff[pg-schema-diff] and similar schema diffing solutions:: I liked the idea, but\nnone of the implementations seemed to be complete enough, and usage of raw sql does not permit the implementation of\n\u003c\u003ctypes-goal,user-defined types\u003e\u003e. They also don't provide good enough solution to storing the schema history, and\nmost useable tools \u003c\u003cautonomous-goal,require the connection to the database\u003e\u003e.\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcertainlach%2Fimmigrant","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcertainlach%2Fimmigrant","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcertainlach%2Fimmigrant/lists"}