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?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.
I posted this in https://ask.datomic.com/index.php/1890/failing-error-message-about-missing-unreadable-maven-artifact
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.
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.
do you just need to enforce uniqueness, or do you specifically need an index?
some other options: https://favila.github.io/2023-07-28/unique-composite-attribute-footguns/
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)
I need to enforce uniqueness.
yea, I didn't want to reach for the tx function and db/ensure before exploring a more data/metadata driven way.
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.
I'm going to reflect on the post, thanks
> 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?
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
“Arbitrary transactions” I should say arbitrary tx data does not compose into a transaction