-
I'm new to electrodb, and I'm using it to interact with an existing DynamoDB database. We're not using a single table, but have about 150 tables that make up our schema. I have this query which does work, but I feel like it could be improved: public async controlsNotInPlace({ ownerGroup }: WithOwnerGroupParams): Promise<number> {
try {
const result: QueryResponse<typeof ControlEntity> = await ControlEntity.query
.controlsByOwnerGroup({ ownerGroup })
.where(
({ inPlace }, { eq, notExists }) => `
${notExists(inPlace)} OR ${eq(inPlace, false)}
`,
)
.go({ data: "raw" });
console.log(">>> result <<<");
// eslint-disable-next-line @typescript-eslint/dot-notation
console.log(result.data["Count"]);
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/dot-notation
return result.data["Count"];
} catch (error) {
// omitted for brevity
}
} My export const ControlEntity = new Entity(
{
model: {
entity: Table.Control,
version: "1",
service: rivialPlatformService,
},
attributes: {
id: {
type: "string",
required: true,
},
ownerGroup: {
type: "string",
required: true,
},
name: {
type: "string",
required: true,
},
createdAt: {
type: "string",
required: true,
validate: (value): boolean => dateRegex.test(value),
},
updatedAt: {
type: "string",
required: true,
validate: (value): boolean => dateRegex.test(value),
},
controlControlSetId: {
type: "string",
},
customFieldData: {
type: "string", // JSON string
},
inPlace: {
type: "boolean",
},
isDisabled: {
type: "boolean",
},
notes: {
type: "list",
items: {
type: "map",
properties: {
content: { type: "string" },
createdAt: { type: "string" },
id: { type: "string" },
owner: { type: "string" },
},
},
},
statementNumber: {
type: "string",
},
templateID: {
type: "string",
},
},
indexes: {
primary: {
pk: {
field: "pk",
composite: ["id"],
},
sk: {
field: "sk",
composite: [],
},
},
controlsByOwnerGroup: {
index: "controlsByOwnerGroup",
pk: {
field: "ownerGroup",
composite: ["ownerGroup"],
},
},
gsiControlSetControls: {
index: "gsi-ControlSetControls",
pk: {
field: "controlControlSetId",
composite: ["controlControlSetId"],
},
},
listControlsByControlSet: {
index: "listControlsByControlSet",
pk: {
field: "pk_owner",
composite: ["ownerGroup"],
},
sk: {
field: "sk_control",
composite: ["controlControlSetId"],
},
},
// ...commonIndexes,
},
},
{ client, table: getTableName(Table.Control), logger },
); The
The other
My basic questions boil down to:
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hey @dbudwin 👋 Firstly, I want to mention the execution option Now to your questions:
Raw is an escape hatch for things like this that don't have a proper implementation yet. I started a branch locally to change the response typing on
My suggestion would be some type guards like this until a more first class feature becomes available.: function hasCount(data: unknown): data is { Count: number } {
return !!data && typeof data === "object" && "Count" in data && typeof data.Count === "number";
}
function toCount(data: unknown): number {
if (hasCount(data)) {
return data.Count;
}
return 0;
}
async function controlsNotInPlace({ ownerGroup }: WithOwnerGroupParams): Promise<number> {
const result = await ControlEntity.query
.controlsByOwnerGroup({ ownerGroup })
.where(
({ inPlace }, { eq, notExists }) => `
${notExists(inPlace)} OR ${eq(inPlace, false)}
`,
)
.go({
data: "raw",
params: {
Select: 'COUNT' // <---- note I am adding this to the parameters sent to the request
}
});
return toCount(result.data);
}
Hope this Helps! Let me know if you'd like to dig a bit deeper into any of these concepts! |
Beta Was this translation helpful? Give feedback.
Hey @dbudwin 👋
Firstly, I want to mention the execution option
{ ignoreOwnership: true }
, which will remove filters added by ElectroDB to help isolate items in some types of queries. ElectroDB internally manages two fields similar to__typename
, and this option removes checks for these fields (which your items naturally won't have).Now to your questions:
Raw is an escape hatch for things like this that don't have a proper implementation yet. I started a branch locally to change the response typing on
{ data: "raw" }
but hit a few sticking points tonight.