I have a web application based on ASP Core 1 with PostgreSql data storage. And now i want to add auth functionality. I have created base example mvc project with authorization and it works fine with MsSql server. But what about PostgreSql?
At first i create database with same schema (sql was generated via dnx ef migrations script and code was updated with pg-style). Then i have configured EF with Postgres
services.AddEntityFramework()
.AddNpgsql()
.AddDbContext<ApplicationDbContext>(options =>
options.UseNpgsql(Configuration["Data:DefaultConnection:ConnectionString"]));
When i try to register as new user, i get an error 42P01: relation \"AspNetUsers\" does not exist. I have already surrounded table name with doublequotes, but it does not helps. I have no access to default auth models and can't add name atribute to table name and name of fields.
So, my questions are:
What wrong with my sample project and why i can't get access to db?
More globally. What is the best way to organize authorization and authentication with ASP Core 1 + PostgreSql? I no needed in all ASP auth features, i just neede in roles, i want to have bigint-based id and i want to extend users model (table).
Note: I use EF7.
So the answer for my first question is in the wrong database schema. For someone interested in schema i get the full pg sql code, but my second question is still opened.
CREATE TABLE public."AspNetRoles" (
"Id" character varying(450) NOT NULL,
"ConcurrencyStamp" text,
"Name" character varying(256),
"NormalizedName" character varying(256),
CONSTRAINT pk_identityrole PRIMARY KEY ("Id")
);
CREATE TABLE public."AspNetUsers" (
"Id" character varying(450) NOT NULL,
"AccessFailedCount" integer NOT NULL,
"ConcurrencyStamp" text,
"Email" character varying(256),
"EmailConfirmed" boolean NOT NULL,
"LockoutEnabled" boolean NOT NULL,
"LockoutEnd" timestamp without time zone,
"NormalizedEmail" character varying(256),
"NormalizedUserName" character varying(256),
"PasswordHash" text,
"PhoneNumber" text,
"PhoneNumberConfirmed" boolean NOT NULL,
"SecurityStamp" text,
"TwoFactorEnabled" boolean NOT NULL,
"UserName" character varying(256),
CONSTRAINT pk_applicationuser PRIMARY KEY ("Id")
);
CREATE TABLE public."AspNetRoleClaims" (
"Id" serial NOT NULL,
"ClaimType" text,
"ClaimValue" text,
"RoleId" character varying(450),
CONSTRAINT pk_identityroleclaim PRIMARY KEY ("Id"),
CONSTRAINT fk_identityroleclaim_identityrole_roleid FOREIGN KEY ("RoleId")
REFERENCES public."AspNetRoles" ("Id") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
);
CREATE TABLE public."AspNetUserClaims" (
"Id" serial NOT NULL,
"ClaimType" text,
"ClaimValue" text,
"UserId" character varying(450),
CONSTRAINT pk_identityuserclaim PRIMARY KEY ("Id"),
CONSTRAINT fk_identityuserclaim_applicationuser_userid FOREIGN KEY ("UserId")
REFERENCES public."AspNetUsers" ("Id") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
);
CREATE TABLE public."AspNetUserLogins" (
"LoginProvider" character varying(450) NOT NULL,
"ProviderKey" character varying(450) NOT NULL,
"ProviderDisplayName" text,
"UserId" character varying(450),
CONSTRAINT pk_identityuserlogin PRIMARY KEY ("LoginProvider", "ProviderKey"),
CONSTRAINT fk_identityuserlogin_applicationuser_userid FOREIGN KEY ("UserId")
REFERENCES public."AspNetUsers" ("Id") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
);
CREATE TABLE public."AspNetUserRoles" (
"UserId" character varying(450) NOT NULL,
"RoleId" character varying(450) NOT NULL,
CONSTRAINT pk_identityuserrole PRIMARY KEY ("UserId", "RoleId"),
CONSTRAINT fk_identityuserrole_applicationuser_userid FOREIGN KEY ("UserId")
REFERENCES public."AspNetUsers" ("Id") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_identityuserrole_identityrole_roleid FOREIGN KEY ("RoleId")
REFERENCES public."AspNetRoles" ("Id") MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
);
I transfer my database from SQL SERVER to postgreSQL, after transfer, I found this error. when I checked my database, the table was in lowercase. I changed all AspTables and columns to default name and solved my problem.
Related
The Goal
I am trying to make two tables, `users` and `clients`, wherein `clients` has a foreign key called `userId` that references the `id` primary key of `users`.
Shows the desired relationship between the tables users and clients
The Migrations
Users
exports.up = function(knex) {
return knex.schema
.createTable('users', function (table) {
table.increments().primary();
table.string('username').unique().notNullable();
table.string('email').unique().notNullable();
table.string('password').notNullable();
table.boolean('admin').notNullable().defaultTo(false);
});
};
Clients
I have tried a variety of different variations of this, which I will show here along with their results:
exports.up = function(knex) {
return knex.schema
.createTable('clients', function (table) {
table.increments().primary();
table.string('name').notNullable();
table.string('secret').notNullable();
table.integer('userId').unsigned().references("id").inTable("users").onDelete("CASCADE");
});
};
This resulted the successful creation of the database, however, the SQLite Viewer indicated that clients.id was somehow referencing a users.userId, as shown in the following image.
exports.up = function(knex) {
return knex.schema
.createTable('clients', function (table) {
table.increments().primary();
table.string('name').notNullable();
table.integer('userId').unsigned();
table.string('secret').notNullable();
table.foreign('userId').references("users.id").onDelete("CASCADE");
});
};
This produced the exact same result as the previous code.
What am I doing wrong?
Edit: An Additional Complicating Factor
I have tried swapping `userId` and `id` in the first attempt at making the clients table. While this did appear to work for the clients table, when I tried to do the same for a `codes` table, I encountered an error that seemed to indicate swapping the two wasn't doing what I hoped it would do. This is consistent with what I've seen in tutorials. I'm inclined to think I was closer to the correct answer at the beginning.
exports.up = function(knex) {
return knex.schema
.createTable('codes', function (table) {
table.string('value').notNullable();
table.string('redirectUri').notNullable();
table.integer('userId').unsigned();
table.integer('clientId').notNullable();
table.foreign('id').references("userId").inTable("users").onDelete("CASCADE");
});
};
Error: create table codes (value varchar(255) not null, redirectUri varchar(255) not null, userId integer, clientId integer not null, foreign key(id) references users(userId) on delete CASCADE) - SQLITE_ERROR: unknown column "id" in foreign key definition
I need help (Problem inside code.)
var db = new SQL.Database(); //instead of creating a new Database , i want to access one.
db.run("CREATE TABLE todos (id INTEGER PRIMARY KEY AUTOINCREMENT, item TEXT);");```
I'm using Mongodb Realm.
I know it is possible to 'createOrUpdate' in realm by using the primary key i.e If the primary key doesn't exists create a new object, If it does update the object.
Something like
realm.write(() => {
// Create a book object
realm.create('Book', {id: 1, date: '12-12-2020', price: 35});
// It will update the price but won't create a new object since the id is the same
realm.create('Book', {id: 1, date: '12-12-2020', price: 55}, 'modified');
});
The realm docs says that
If your model class includes a primary key, you can have Realm
intelligently update or add objects based off of their primary key
values. This is done by passing true as the third argument to the
create method:
this can be found here https://docs.mongodb.com/realm-legacy/docs/javascript/latest/#creating-and-updating-objects-with-primary-keys
NOW, I want to update the Object based on a different field(key) apart from the primary key and On this case it is the date field This is to say that, If the date doesn't exist, create a new object/entry but it it does, just update the price.
How do I do this with realm?
I'm making an app using Ionic 3 and SQLite. I tried to create a table using a property as table name inside the query but it returns this error:
'sqlite3_prepare_v2 failure: near "(": syntax error'
Here's the code that I used:
onCreateTb() {
this.database.executeSql('CREATE TABLE IF NOT EXISTS (?) (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, skill TEXT, yearsOfExperience INTEGER)', [this.tableName])
.then(() => console.log('Ok'))
.catch(error => console.log(error));
}
In various articles about SQLite I saw the (?) marker on INSERT queries but never on CREATE TABLE queries.
How can I use a property as a table name?
I'm currently researching on Ignite, and I used web-console's automatic RDBMS integration feature for my MariaDB persistent store.
This made ignite configure a cache for one of my reference table which has a many-to-many relationship, with 2 fields, both primary-keys.
Example Structure in the persistent store:
CREATE TABLE `user_category` (
`USER_ID` bigint(20) NOT NULL,
`CATEGORY` bigint(20) NOT NULL,
PRIMARY KEY (`USER_ID`,`CATEGORY`),
KEY `FK48520EF2B4BDA303` (`USER_ID`),
KEY `FK48520EF2C941D634` (`CATEGORY`),
CONSTRAINT `FK48520EF2B4BDA303` FOREIGN KEY (`USER_ID`) REFERENCES `ctrl_app_user` (`USER_ID`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK48520EF2C941D634` FOREIGN KEY (`CATEGORY`) REFERENCES `request_category` (`CATEGORY_ID`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
This made web-console configure the cache like this:
ArrayList<QueryEntity> qryEntities = new ArrayList<>();
QueryEntity qryEntity = new QueryEntity();
qryEntity.setKeyType("model.UserCategoryKey");
qryEntity.setValueType("model.UserCategory");
qryEntity.setTableName("user_category");
HashSet<String> keyFields = new HashSet<>();
keyFields.add("userId");
keyFields.add("category");
qryEntity.setKeyFields(keyFields);
LinkedHashMap<String, String> fields = new LinkedHashMap<>();
fields.put("userId", "java.lang.Long");
fields.put("category", "java.lang.Long");
qryEntity.setFields(fields);
HashMap<String, String> aliases = new HashMap<>();
aliases.put("userId", "USER_ID");
qryEntity.setAliases(aliases);
ArrayList<QueryIndex> indexes = new ArrayList<>();
QueryIndex index = new QueryIndex();
index.setName("FK48520EF2B4BDA303");
index.setIndexType(QueryIndexType.SORTED);
LinkedHashMap<String, Boolean> indFlds = new LinkedHashMap<>();
indFlds.put("userId", false);
index.setFields(indFlds);
indexes.add(index);
index = new QueryIndex();
index.setName("FK48520EF2C941D634");
index.setIndexType(QueryIndexType.SORTED);
indFlds = new LinkedHashMap<>();
indFlds.put("category", false);
index.setFields(indFlds);
indexes.add(index);
qryEntity.setIndexes(indexes);
qryEntities.add(qryEntity);
ccfg.setQueryEntities(qryEntities);
return ccfg;
I am able to retrieve data from ignite properly using its standard SQL.
However, when trying to insert data to that cache, I am getting error 50000 which according to Ignite documentation, is a query that is unsupported by ANSI-99.
Documentation also mentioned to take a look into the SQLException message but the message only mentioned the error 50000.
sample insert statement:
insert into USER_CATEGORY (USER_ID, CATEGORY) values (1, 1);
Thanks in Advance.
Most likely you need to specify a schema name (cache name) for the query:
insert into "YourCacheName".USER_CATEGORY (USER_ID, CATEGORY) values (1, 1);
So, for everyone who will experience this issue in the future, I've resolved the issue by removing the query entity keys.
keyFields.add("userId");
keyFields.add("category");
Ignite treats keys in a reference table/cache as unique, so both columns needed to be unique, this is not applicable for reference tables with many-to-many relationship since this design is bound to have duplicates for each column.
Thanks for those who took a look at this issue!~