Unique typeorm. query(sqlQuery); I am trying to get something like this.

Contribute to the Help Center

Submit translations, corrections, and suggestions on GitHub, or reach out on our Community forums.

例如:. Works in NodeJS, Browser, Ionic Apr 3, 2018 · createdAt: Date; @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP', onUpdate: 'CURRENT_TIMESTAMP', nullable: false }) updatedAt: Date; } In this case typeORM ended up generating unique key constraint on roleId in users table which prevents to have multiple users with same roleId and is against the requirement a role can belongs to May 27, 2019 · Steps to reproduce or a small repository showing the problem: Hi guys, I'm trying to have unique keys with foreign key associated with one of them but I think typeorm is creating different unique keys. Feature. There is no @PrimaryColumn or @PrimaryGeneratedColumn in it. Jun 14, 2020 · I am trying to create an index with multiple fields, one of the field is a foriegn key to another table. Default value is false. Learn how to create and use indices for columns, multiple columns, unique columns, and spatial columns in TypeORM. Jul 20, 2021 · Here GitHub TypeORM EntitySchemaOptions you can see which options you have, when creating a new EntitySchema. TypeORM is able to automatically generate migration files with schema changes you made. However, the Faker in typeorm-seeding's package. Dec 6, 2019 · create unique index on the_table (coalesce(a,-1), coalesce(b, -1), coalesce(c, -1)); That way NULL values are treated the same inside the index, without the need to use them in the table. API with NestJS #53. 19 (or put your version here) Steps to reproduce or a small repository showing the problem: Please tell me. json’. 你可以在实体中定义任何名称的方法,并使用 @BeforeUpdate 标记,TypeORM 将在使用 repository/manager save 更新现有实体之前调用它。. find({ skip: 5, }) SELECT * FROM "user" OFFSET 5. Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, MongoDB databases. @PrimaryColumn() userLastName: string. If related entity has multiple primary keys, and you want to point to multiple primary keys, you can define multiple primary columns the same way: @PrimaryColumn() userFirstName: string. getRepository('order'); await orderRepo. After 2nd save call, I get "duplicate key", beacuse typeorm is inserting instead of updating, beacuse typeorm does not check for unique key, but primary key. Typeorm takes the typing of a field and tries to create that database field based on the typing it reads. Hope this helps! Dec 9, 2019 · I have many to one relation with typeorm constructed like this: In PostEntity Class. To make them required you need to explicitly change their nullable state, e. This is what I have. addSelect(' One-to-one is a relation where A contains only one instance of B, and B contains only one instance of A. It should also be noted that, as explained in the type-safety section below , TypeORM loses type-safety in filter queries in many scenarios. schema - schema name. ts Jul 2, 2018 · In your case you did not sent any properties TypeORM needs, so for typeorm your object is basically {}. TypeORM Upsert is used to check if the object exists and do an insert, although I don't see a way to use that in the same way you've done a cascade insert: cascade: ["insert"] }). Works in NodeJS, Browser, Ionic Feb 19, 2018 · Currently only unique index. so i Declaration. PostgreSQL has a built in enum type, but unfortunately TypeORM currently only supports it for MySQL. One such approach is in Naming conventions in SQL. Apr 30, 2021 · 1. js server-side applications. userRepository. save() is throwing duplicate key value violates unique constraint when uuid is lowercase Expected Behavior I expect that the data is saved in teh database without any problems as everything works out when I convert uui ORM for TypeScript and JavaScript. @ 由于不同的数据库特性和关于现有数据库索引信息获取和自动同步的多个问题,TypeORM 不支持某些索引选项和定义(例如 lower 、 pg_trgm )。. select('id') . 2. You can create an entity by defining a new class and mark it with @Entity(): import { Entity, PrimaryGeneratedColumn, Column } from "typeorm" @Entity() export class User { @PrimaryGeneratedColumn() id: number @Column() firstName: string @Column() lastName Apr 22, 2021 · TypeORM: update entity column with relation (@joinColumn) via Repository. @ Entity() export class User {. I'm trying to create a postgres database using typescript and typeOrm. 25 (or put your version here) Steps to reproduce or a small repository showing the problem: I use @JoinTable decorater and I want to create UNIQUE constraint on two JoinTable column, fk_question_id, fk_question_id. This command will run the migration which you have already created in the above command. The `save` method is used to create new records, while the `update` method is used to update existing records. Configure TypeORM : Now that TypeORM is installed, you need to configure it to connect to your database. I can succesfully create migrations but when I tried to run it throws error: query failed: ALTER TABLE "post" ADD CONSTRAINT "FK_f36f38b0231a9075541aae12b73" FOREIGN KEY ("user_posted_id") REFERENCES "user" ("id") ON DELETE NO ACTION ON ORM for TypeScript and JavaScript. // Drop indexes and unique constraints on Feb 9, 2021 · Im trying to use typeorm softdelete feature , for deleting its fine ,adds a timestamps to deletedAt field but the problem emerges when you have unique field like "username" and you softdeleted it then trying to add another record with the same "username" field value as deleted record . I tried to install the latest Faker myself, but it is not unique because it runs on a new Faker instance each the factory is Dec 13, 2017 · If you are on PostgreSQL you could just write a raw query that performs the update and returns it ( see this) eg. I am new to TypeORM and Nest. View entity is a class that maps to a database view. API with NestJS #51. API with NestJS #52. Consider executing sql if you need exactly constraints. Example: import { Entity, PrimaryGeneratedColumn, Column, Index } from "typeorm". Jun 19, 2021 · I use NestJS + TypeORM softRemove/softDelete for delete records. There are two approaches that can be used to solve this problem. In #1090, TypeORM supported orUpdate in its query builder to support upsert. Here is the way I make the primary key with Typeorm in Nestjs entity file named 'email'. I have the following entities: So, the wallet table is looks like this: And I like to update the wallet entity via Repository api. @Column({ unique: true, nullable: true, }) resetPasswordToken!: string; This is also where lies my problem. Jul 26, 2023 · npm install @nestjs/cli @nestjs/common @nestjs/core @nestjs/typeorm @nestjs/passport @nestjs/jwt typeorm passport passport-jwt mysql2. Jul 7, 2017 · 48. take - limit (paginated) - max number of entities that should be taken. I have entity with unique field. Dec 9, 2020 · npm run typeorm migration:run. I have a table called 'alert' that contains a column called ID which is a unique column. Use node-ts instead of nest start solved the problem without modifying the path of the entities file. Can i use @Unique decorator to check the email field for uniqueness? And if so, how is this possible? User. leftJoin('user. Dec 2, 2021 · In my backend using nestjs + typeorm + postgresql I have a CustomRepository and want to repalce some plain sql queries. My remove method like: return await this. nest start. 1. find(userId) const newOrganization= new Organization({organizationParams}) user. TypeORM Custom Repository, select distinct values from Nov 6, 2021 · In such cases you should create index manually (for example in the migrations) with any index signature you want. 4. 你可以在实体中定义任何名称的方法,并使用 @AfterUpdate 标记,TypeORM 将在使用存储库/管理器 Data-Mapper ORM for TypeScript, ES7, ES6, ES5. Generating documentation with Compodoc and JSDoc; 53. Aug 17, 2022 · This happened when i upgraded typeorm to the latest version. – Chidiebere. npm run typeorm migration:revert. username = nameToSave; Jan 6, 2020 · Steps to reproduce or a small repository showing the problem: I'm new using typeorm and I'm having a trouble, I have created an entity that creates a user un my database, and also defined a unique constraint decorator an it still creating the user in my database when I test the Api with postman it doesn't show any errors. Complete support for unique constraints expect in 0. I have char type primary key length of 39, and have put a unique string made up of UUID concatenate with some extra sting in it. TypeORM primarily leans on SQL operators for filtering lists or records, e. usersRepository. An example would be: new EntitySchema({. When would you use which, and what's the difference there? @Unique(["firstName"]) https://typeorm. const user = this. By understanding the difference between the `save` and `update` methods, you can use them effectively to manage your data in TypeORM. 了解有关 listeners 的更多信息。. createQueryBuilder('user') . And here you can see how you use uniques. ``` UPDATE <table-name> SET c=value RETURNING * ``` If you are not using Postgres then you might as well just perform an update and a find in a transaction. Introduction to logging with the built-in logger and TypeORM; 51. but when I'm trying to add a new user with the following code I get this error: // Adds a user to the database. I started working with typeORM a while ago and encountered a problem. But for conditional I have no idea :(Could anyone help me? Relevant Database Driver(s) postgres; Are you willing to resolve this issue by submitting a Pull Request? Yes, I have the time, and I know how to start. typeorm querybuilder: select relation of relation only. Jul 9, 2021 · I want to union two tables in typeorm. id: {. You can create indices for any columns of your entity. However i get the following error: Error: Index "player_id_UNIQUE" contains column that is Dec 1, 2021 · How do you set a custom default unique id string for the @PrimaryGeneratedColumn in a TypeORM Entity? 8 How can I specify column name casing in TypeORM migrations May 11, 2021 · ormconfig. You can use the . Aug 9, 2021 · With the unique constraint, we can ensure that the values in the column are unique across all of the rows in the table. Connect and share knowledge within a single location that is structured and easy to search. If you are trying to save a post that already exists, then you should pass the id value as well. const data = [. I'd like to bulk insert or update if exists rows in a table without prior knowledge of the id of the row if it exists. I'm using TypeORM. ) We now expect every post to have a unique title. leftJoinAndSelect("leave. In this case, I want to update rows where the uniqueKey exists with a new title, and insert where it does not. Jun 3, 2021 · For creating Unique constraint I used to add decorator @Unique(['col_a', 'col_b']) before the entity. EDIT: This answer is still valid but a bit outdated as 0. CREATE TABLE posts (. ts Custom validation decorators. address that is checking uniqueness. If those columns are numeric or float (rather than integer or bigint) using '-Infinity' might be a better substitution value. . I'm on a plain TS stack, nothing fancy atm. json[entities]' Oct 4, 2021 · One of the most popular Object Relational Mapping or ORM is TypeORM. Entity is a class that maps to a database table (or collection when using MongoDB). js, I might have asked a dumb question but I am getting any solution for it. name: "Example", columns: {. js ORMs. softDelete(id); In Entity will be perfect something like: @Column({ type: 'varchar', nullable: false })//may be exists some expression for column settings. Jul 6, 2022 · How can I tell typeorm to only use the predefined join column in join table? Update 2 (as mentioned by @suvantorw) I recreated the join table with the statement below: In this chapter, we'll demonstrate using the popular MySQL Relational DBMS, but TypeORM provides support for many relational databases, such as PostgreSQL, Oracle, Microsoft SQL Server, SQLite, and even NoSQL databases like MongoDB. 3. The problem appears to be that TypeORM does not accept entities in the form of typescript files. But currently, it is only possible to perform an upsert when the single column violation happens. console. Jul 28, 2023 · In sequelize, I used unique property in "email" and "code" column and that helped me to write Upsert functionality. TypeORM does not support some index options and definitions (e. query(sqlQuery); I am trying to get something like this. TypeOrm query builder. Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, SAP Hana, WebSQL databases. Sep 22, 2022 · With over 29. import { Factory } from '@linnify/typeorm-factory'; export class NormalUserFactory extends Factory<User> { entity = User; firstName = 'John' lastName = 'Doe' email = 'john. This command will revert the migration which you have already executed in the above Feb 14, 2019 · 2. Aug 16, 2022 · CREATE UNIQUE INDEX index ON BAR (foo) WHERE foo IS NULL; -> this creates a unique index on all foo values but only considers rows where foo is null. Issue Description Expected Behavior Typeorm should detect the unique constraint for column was already created and skip its creation. organizations. Steps to Reproduce. At first lets talk a bit about ORM. import { Injectable } from '@nestjs/common'; import { registerDecorator, ValidationArguments, ValidationOptions, ValidatorConstraint, ValidatorConstraintInterface, } from 'class-validator'; import { DataSource } from 'typeorm'; Nest (NestJS) is a framework for building efficient, scalable Node. : @Column({ nullable: false }) firstName: string; answered Jul 2, 2018 at 18:35. Let's take for example User and Profile entities. x (or put your version here) Hello. Faker uses the unique() method to generate unique values. save({id: 1, name : "New Contraption Name !"}); This solution is not an actual upsert, it's just an update. Nov 1, 2020 · Typeorm casts the code below to a varchar field in my postgres database because I gave it a string as a type in typescript. Relevant Database Driver(s) aurora-data-api; aurora-data-api-pg; better-sqlite3; cockroachdb; cordova; expo; mongodb; mysql; nativescript Jan 16, 2022 · Teams. here is my new solution. 2. g. Actual Behavior Typeorm does not detect the constraint is present and tries to create it again: error: Column indices. tableUnion. approvedBy", "users") . When you run this command, it will execute the up function in the migration file. Dec 28, 2020 · API with NestJS #50. Just combine @ManyToOne and @JoinColumn decorators together like this: @ManyToOne(type => Category) @JoinColumn({ name: 'custom_field_name_if_you_want' }) category: Category; May 6, 2023 · What is TypeORM? TypeORM is a powerful ORM (Object-Relational Mapping) library that makes it easy to work with databases in TypeScript or JavaScript. json is an older version and does not implement the unique() method. Mar 25, 2021 · I also use composite keys with TypeORM and encountered some trouble. For the Primary key, the name should be in the format PK_. If you want to create and index you should use the annotation @Index of Typorm. See an example with a products table and a Product entity. find({select:["myColumn"]}); // note the missing DISTINCT upsert typeorm function not working. when generate, typeorm first reads ormconfig. it doesn't accept it ,since its already inserted once and database has no perception of the softdelete . You can create a view entity by defining a new class and mark it with @ViewEntity(): name - view name. It uses progressive JavaScript, is built with and fully supports TypeScript (yet still enables developers to code in pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional However, they have different purposes and use cases. Mar 19, 2019 · When that same record is attempted to be inserted again, the unique constraint is not met and as expected the record is not inserted. insert(data); TypeORM has no idea what your intent is when you try to save the new Post 7 object and it does not know that it already exists in the database (the identity field is missing). Revert the migration. Let's say you have a Post entity with a title column, and you have changed the name title to name. user. createQueryBuilder('tu') . 在这种情况下,您应该手动创建索引(例如在迁移中),并使用任何您想要的索引签名。. If not specified, then view name is generated from entity class name. You can create a database index for a specific column by using @Index on a column you want to make an index. return this. A simple typeorm + Postgresql stack should suffice. With PostgreSQL, we can also expect a group of columns to have a unique value. 20, last published: 6 months ago. Implementing soft deletes with PostgreSQL and TypeORM; 54. Here is an example to count articles for each users using the TypeOrm QueryBuilder: async findUsers(): Promise<UsersEntity[]> {. json and login into rdbms. Save. But the problem is, that I can't just: Because Typescript give me an error, that userId should be userEntity, but not number. Nov 24, 2018 · find will return an array, you should check the length of the array to confirm the rows match the WHERE clause executed. Jun 9, 2020 · TypeORM version: [ ] latest [ ] @next [x] 0. To make TypeORM ignore these indices during synchronization use synchronize: false option on @Index decorator. For declaring a factory, we make use of typescript classes and add as properties on the class the fields from our entity with the desired values. Start using typeorm in your project by running `npm i typeorm`. if I remove unique:true anything goes fine! import { Entity, PrimaryGeneratedColumn, CreateDateColumn, Column, enter code here BeforeInsert, } from 'typeorm'; import * as bcrypt from 'bcryptjs'; import Sep 4, 2018 · I have a use case that calls for a custom string primary key in my tables. Aug 16, 2017 · The erroneous shorter name seems to be the culprit, as TypeORM probably expects the long name when trying to determine if the unique constraint already exists. x. 0. ts. discord_id = idToSave; user. There is a drawback to this though: Sep 4, 2022 · Learn how to use TypeORM to select distinct values from a table using the select and distinct methods. entity. Latest version: 0. doe@typeorm Sep 29, 2022 · TypeOrm Insert does not check if the object exists, it's the unique flag for Sender. Example: import { Entity, PrimaryGeneratedColumn, Column, Index } from "typeorm" @Entity() export class User { @PrimaryGeneratedColumn() id: number @Index() @Column() Mar 14, 2019 · TypeOrm will automatically create foreign key property when you use @ManyToOne decorator. user", "users") So at the end your query will end up with smth like this: SELECT * FROM leave LEFT JOIN users AS users LEFT JOIN users AS users To fix that you have to name it different, fe: Does typeorm provide a solution for such cases ? The text was updated successfully, but these errors were encountered: 👍 16 sladg, smblee, apyrkh, wayoalamos, hkjasf687261gh, Nicoowr, alondahari, romitamgai, ao-alex, inmativ, and 6 more reacted with thumbs up emoji Jan 7, 2020 · TypeORM version: [x] latest [ ] @next [ ] 0. See examples, options, and limitations for different databases. import { Entity, PrimaryGeneratedColumn, Column } from "typeorm" @Entity() export class Profile May 29, 2021 · I would like to follow SQL naming standards for Primary and Foreign Key names. 9. Prisma ORM on the other hand, provides a more generic set of operators that are intuitive to use. Feb 28, 2021 · 1. When I try to insert to the DB a row with an ID that already exists in the table, the row does not enter the table but my code gets no error, it thinks that everything is fine. Simple example of QueryBuilder: May 20, 2024 · but later when I need to add a new organization and save it, it gives unique constraint violation for (user_id, organization_id) as it tries to save the old user organizations again. database - database name in selected DB server. io/#/decorator-reference/unique. In a nutshell, you can craete or query data from a relational database using object oriented way with ORM. The procedure we walk through in this chapter will be the same for any database supported by TypeORM. So upserting with typeORM is : let contraption = await thingRepository. And when adding a column to an existing table and immediately specifying unique: true for that new column, then the UNIQUE constraint is not added immediately. with the find method. @Column({ unique: true }) firstName: string; Oct 19, 2023 · Issue description . However, postgres' default action is to allow multiple NULL values even with a unique index (its unique for non-null values) so this would still allow you to insert 2 entries into BAR where foo IS Sep 8, 2020 · In TypeORM you have the possibility to set a unique flag in the column options, or to set column (s) to unique for the entity. In UserEntity Class. Here is my model file: import { Column, Entity, JoinColumn, OneToOne, PrimaryGeneratedColumn, Unique, } from 'typeorm'; import { BotModel } from unique: boolean - Marks column as unique column (creates unique constraint). I am making a table for an email with Nestjs, MySQL, and Typeorm. Jun 1, 2023 · To be honest I don't know if for @ManyToOne, @OneToMany, @OneToOne, @ManyToMany or @Column({ unique: true }) Typeorm create indexes, maybe it depends on the DB at least for my case I'm using MSSQL and Typeorm (or the DB itself) create the primary key index. In the ‘src’ folder of your project, create a new file called ‘ormconfig. However, you could achieve a similar result with an int-type enum by using the @Column type as int and using 如果未指定,则 TypeORM 将从实体和列名生成枚举类型 - 因此,如果您打算在不同表中使用相同的枚举类型,这是必需的。 primaryKeyConstraintName: string - 主键约束的名称。如果未指定,则约束名称将根据表名和涉及的列的名称生成。 asExpression: string - 生成的列表达式。 Mar 1, 2017 · Hi there, I got two tables defiened like this: @Entity("A") export class Issue { @PrimaryGeneratedColumn() id: number; @Column({default: ""}) title: string TypeORM version: [ ] latest [ ] @next [x] 0. What happens with the current findOne implementation is that when a row is not found with the required values, the first row of the table in question is being returned. In such cases you should create index manually (for example in the migrations) with any index signature Nov 22, 2019 · Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers; Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand Defining subdocuments (embed documents) Since MongoDB stores objects and objects inside objects (or documents inside documents) you can do the same in TypeORM: import { Entity, ObjectId, ObjectIdColumn, Column } from "typeorm" export class Profile { @Column() about: string @Column() education: string @Column() career: string } Dec 21, 2019 · And run by using command. Create your database models. Q&A for work. this. and compares between 'the actual schema of db' and 'schema file as ormconfig. push(newOrganization) import { ObjectType, SelectQueryBuilder } from "typeorm"; /* * entityType - TypeORM Entity * obj - Object to upsert * key_naming_transform (optional) - Transformation to apply to key names before upsert * do_not_upsert - Keys to exclude from upsert. Learn more about Teams May 27, 2021 · The factory cannot generate unique values. Oct 14, 2017 · But if you do not specify the id or unique set of fields, the save method can't know you're refering to an existing database object. User can have only a single profile, and a single profile is owned by only a single user. 0 alpha versions of TypeORM support enums for both PostgreSQL and MySQL. (I don't want to use the default 'uuid' provided by GraphQL, but instead want to use the shortid library to generate a custom unique id instead. If you are trying to have the composite key consisting of two columns, I would just set 'userId' and a 'taskCount' as the the composite primary key, which I think is the better solution here. In TypeORM, your database models are defined using TypeScript classes. primary: true, type: Number. {title: 'New Title', user: 123, uniqueKey: 'abc'}, Jun 26, 2022 · user: User. Maybe something like this: Dec 26, 2023 · To insert data with relations using typeorm, you can use the following steps: 1. but anyway I'm gonna share my solution when i used old version. lower, pg_trgm) because of lot of different database specifics and multiple issues with getting information about exist database indices and synchronizing them automatically. Previously i was using this syntax: const orderRepo: Repository<Order> = getConnection(). Health checks with Terminus and Datadog; 52. json is deprecated in latest version as i know. Besides being database agnostic, TypeORM has a unique API that allows you to access data in SQL databases, such as MYSQL and PostgreSQL, and NoSQL databases, like MongoDB, in different ways using Active Record and Data Mapper patterns. Jan 1, 2020 · TypeORM version: [x] latest [ ] @next [ ] 0. 为了在同步期间使 TypeORM 忽略 Sep 8, 2021 · typeOrm unique row. repo. Generating migrations. I am trying to save passing this unique key. QueryBuilder is one of the most powerful features of TypeORM - it allows you to build SQL queries using elegant and convenient syntax, execute them and get automatically transformed entities. 1. Primary column name must match the relation name + join column name on related entity. articles', 'articles') Nov 1, 2021 · Because you name it same, take a look at your query builder: . For each table in your database, you will need to create a corresponding TypeScript class. In some databases unique constraints and unique indices are the same. ) I'm a TypeORM beginner, and I'm not finding anything about setting a custom default primary key in the docs. x (or put your version here) Steps to reproduce or a small repository showing the problem: Hi, when I'm saving an entity with date as pk im running into a unique constraint error: You can create a database index for a specific column by using @Index on a column you want to make an index. still inserting even i defined the column that should be unique 👍 5 fabiano-ig, Flenz42, Number16BusShelter, nojitsi, and paparrot reacted with thumbs up emoji find* methods which return multiple entities ( find, findBy, findAndCount, findAndCountBy) also accept following options: skip - offset (paginated) from where entities should be taken. My Environment. What do you think. API with NestJS #54. loadRelationCountAndMap query method to count elements from your relation. this is my error: QueryFailedError: ER_BLOB_KEY_WITHOUT_LENGTH: BLOB/TEXT column 'username' used in key specification without a key length. 3k stars on GitHub, TypeORM is one of the most popular Node. And I want to apply @Unique decorator only for undeleted records. The problem is that the whole app crashes when this constraint is not met and I have to restart the app in order to get it back online again. 3. add a file name is-unique. Please explain me why do you add groupName to the primary key if you already have an auto-generated unique id? Wouldn't you rather want a simple primary key on id and a unique constraint on groupName? Jul 15, 2021 · 1. In the Article class add the @Index decorator and disable synchronization to avoid deletion on the next schema sync Jun 10, 2021 · with a QueryFailedError: duplicate key value violates unique constraint. save({}) is valid in your case since all columns in your aren't required. const sqlQuery = `SELECT DISTINCT "myColumn" FROM "myTable"` const sqlRes = await this. log("Inserting a new user into the database"); const user = new dbUser(); user. As the name suggests, ORM is a programming technique that relates or maps object oriented model to relational database model. There are 4447 other projects in the npm registry using typeorm. You can run following command: typeorm migration:generate PostRefactoring -d path-to-datasource-config. Instead, TypeORM adds the Feb 21, 2021 · 11. . Generate it first and insert it into your database. First version: I crated sql raw queries, for each table const tableUn = this. id serial PRIMARY KEY, title text UNIQUE. hn ha mv en cw bb zn qe ug fi