ulysses
ulysses3mo ago

set _creationTime from created_at on migration from other database

hey all. What's the best way to instantiate/overwrite _creationTime? I am migrating data from postgres and need to change the _creationTime for documents to match up with the original created_at time(s)
7 Replies
Convex Bot
Convex Bot3mo ago
Thanks for posting in <#1088161997662724167>. Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets. - Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.) - Use search.convex.dev to search Docs, Stack, and Discord all at once. - Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI. - Avoid tagging staff unless specifically instructed. Thank you!
Hmza
Hmza3mo ago
_creationTime is source of truth in convex, its immutable. should i suggest creating a new field when migrating to convex something like originalCreatedAt and then adding an index on top in the table .index("by_originalCreatedAt", ["originalCreatedAt"]) will essentially work the same for querying as _creationTime. just a suggestion to also add a field migratedAt so you can track migration date/time data seperately later if required.
ulysses
ulyssesOP2mo ago
but this means I always have to maintain a secondary created_at field? I will not be able to remove this column
Hmza
Hmza2mo ago
yeah you can't rewrite history _creationTime but you can keep the past intact originalCreatedAt
ulysses
ulyssesOP2mo ago
but this also means the future is affected? I mean we cannot eventually move to comparing based of _creationTime we will always have to insert a value for created_at and use created_at for the comparison. Is this expected design/behaviour for convex to ignore the system _creationTime?
Hmza
Hmza2mo ago
As I said before, creating an index makes your createdAt field just as efficient to query as the system's _creationTime. This means there is no performance overhead and it keeps your code consistent. If you don't want to handle that yourself, there is another layer of customMutation and customQuery ref: https://www.npmjs.com/package/convex-helpers#row-level-security e.g. export const myMutation = customMutation(mutation, customCtx(async (ctx) => ({ db: { ...ctx.db, insert: async (table, value) => { // Always set createdAt automatically return ctx.db.insert(table, { ...value, createdAt: Date.now() }); }, }, }))); now your time field logic is centralized. same for queries: export const myQuery = customQuery(query, customCtx(async (ctx) => ({ db: { ...ctx.db, queryByCreatedAt: (table) => ctx.db.query(table).withIndex("by_createdAt").order("desc"), }, }))); and your business logic never needs to handle createdAt directly. you just use myQuery and myMutation instead of default mutation and query in convex functions.
npm
convex-helpers
A collection of useful code to complement the official convex package.. Latest version: 0.1.95, last published: a day ago. Start using convex-helpers in your project by running npm i convex-helpers. There are 16 other projects in the npm registry using convex-helpers.
ulysses
ulyssesOP2mo ago
got it. Thank you so much for this reply. makes a lot of sense

Did you find this page helpful?