datomic

wevrem 2026-05-19T00:08:56.886679Z

Now I'm having trouble pushing my ions to S3 code bucket. At first I think it was permission errors (hard to tell for sure, I think the instructions are kind of missing important details). So I gave very broad permissions, and now the error changed to this, which to me feels more like a datomic error, not something on my side (my main clue is these S3 endpoints are not mine):

{:command-failed
 "{:op :push :creds-profile \"byt-wrought-test\" :region \"us-west-2\"}",
 :causes
 ({:message
   "Failed to read artifact descriptor for com.datomic:ion-http-direct:jar:1.0.47",
   :class ArtifactDescriptorException}
  {:message
   "Could not transfer artifact com.datomic:ion-http-direct:pom:1.0.47 from/to datomic-cloud (): Unexpected error downloading artifact from datomic-releases-1fc2183a",
   :class ArtifactResolutionException}
  {:message
   "Could not transfer artifact com.datomic:ion-http-direct:pom:1.0.47 from/to datomic-cloud (): Unexpected error downloading artifact from datomic-releases-1fc2183a",
   :class ArtifactTransferException}
  {:message
   "Unexpected error downloading artifact from datomic-releases-1fc2183a",
   :class ExceptionInfo,
   :data
   {:bucket "datomic-releases-1fc2183a",
    :path
    "maven/releases/com/datomic/ion-http-direct/1.0.47/ion-http-direct-1.0.47.pom",
    :reason :cognitect.anomalies/fault}})}
Anyone have any suggestions?

wevrem 2026-05-19T00:40:50.829439Z

I checked the bucket in S3 and there are folders for various versions (1.20, 1.31, 1.56) but it seems to be choking on this mysterious 1.0.47. I have no idea. I'm pointing to all the latest releases of ion, ion-dev, and client-cloud.

wevrem 2026-05-20T00:00:48.369449Z

The fix was not what I was expecting (of course!). Jaret asked a question which prompted me to double check my settings in deps.edn. I made sure that datomic-cloud and ion were in top-level :deps, and :ion-dev alias only included ion-dev. After that I just needed to set up some additional permissions on my IAM policy and it worked.

2026-05-19T16:25:22.840589Z

Looking for the idiomatic Datomic pattern for per-tenant uniqueness on a string. Specifically per (owner, entity-type), e.g. tag slugs unique per owner. Today I have a single :entity/owner ref on every tenant-scoped entity and use d/filter for isolation. A composite tuple [:tag/slug :entity/owner] with :db.unique/identity won't work here. The tuple is populated on any entity that has either constituent, so every non-tag entity ends up with [nil owner-eid] and they collide. Open to redesigning the owner modeling too. Approaches I've considered: - Per-type owner attrs (`:tag/owner`, :note/owner, ...) so the composite is scoped to that type. Implies a meta-schema marking which attrs are owner-bearing so d/filter can find them all. Is that a common pattern? - A heterogeneous value-tuple attr [owner-eid slug] with :db/tupleTypes [:db.type/ref :db.type/string] and :db.unique/identity, asserted only on entities that have a slug. - Something else? Nothing is in production, just exploring the ideal design.

favila 2026-05-19T17:18:25.645569Z

do you just need to enforce uniqueness, or do you specifically need an index?

favila 2026-05-19T17:18:37.774119Z

some other options: https://favila.github.io/2023-07-28/unique-composite-attribute-footguns/

favila 2026-05-19T17:20:03.134769Z

if you don't need an index by value and the cardinality of tags is low, you could enforce this by a transaction function (precondition) or a :db/ensure entity spec predicate (postcondition)

2026-05-20T06:31:29.838549Z

I need to enforce uniqueness.

2026-05-20T06:35:14.785889Z

yea, I didn't want to reach for the tx function and db/ensure before exploring a more data/metadata driven way.

2026-05-20T06:39:12.284429Z

tags is an example, most of my entities plan to have a natural language "handle" (sluggified name or label of the entity) that needs to be unique per type per owner, and some entities have high cardinality.

2026-05-20T06:45:57.197359Z

I'm going to reflect on the post, thanks

2026-05-20T06:49:17.539469Z

> You may have already built your application with a disciplined abstraction layer over the operations you can take. For example, people don’t construct transactions ad-hoc, but use functions that do so, and those functions correspond closely to understood domain-level operations. If this is you, asserting pre- and post-conditions is probably the solution that fits you best. > If you put most of your effort into schema meta-annotation and modeling your domain “at-rest” more than “in-motion”, then perhaps you should lean more into that and make your own annotation-driven data-model operations to enforce your relational invariants. As an experienced datomician, @favila which do you usually lean towards? at-rest or in-motion by default?

favila 2026-05-20T06:57:29.489669Z

If you can only have one: In-motion more than at-rest. Because: at-rest constraints are an emergent property of what all operations can do anyway, the reverse is less constraining; datomic requires an opt-in to most checks, so having a central layer where that is done consistently is more valuable than a description of them; generally arbitrary transactions don't compose, so you have to think up-front anyway

👍 1
favila 2026-05-20T06:58:51.732049Z

“Arbitrary transactions” I should say arbitrary tx data does not compose into a transaction